Skill Level: Intermediate

Basic working of linux and ansible knowledge required.

This article covers configuring systems with Ansible, testing and validating the configuration with Kitchen using Inspec.
We will create an ansible role to install and configure apache. We will test it on a Kitchen instance and use Inspec to valid.


You will need the following tools:

  • ChefDK (3.4.38)
  • VirtualBox (5.2)
  • Vagrant (2.1.2)
  • Ansible (2.9)


  1. Setup Kitchen

    Test Kitchen can be easily installed with ChefDK, which contains all the tools needed for running Test Kitchen. Once ChefDK is installed, run the following to get Kitchen-Ansible

    chef gem install kitchen-ansible
  2. Creating an Ansible Role

    For this article, let us consider an example of an Ansible Role to install and configure apache. To create the role, create the structure as follows:

    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── test
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml


    Update the files as following:

    # vi tasks/main.yml

    # tasks file for apache-role

    - name: Install httpd Package
        name: httpd
        state: latest

    - name: Copy httpd configuration file
        src: files/httpd.original
        dest: /etc/httpd/conf/httpd.conf
        mode: '0644'
        owner: root

    - name: Copy index.html file
        src: files/index.html
        dest: /var/www/html
      - restart apache

    - name: Start and Enable httpd service
        name: httpd
        state: restarted
        enabled: yes             

    Add the two files:

    # ll files/*
    -rw-r--r-- 1 root root 11753 Feb  4 10:01 files/httpd.original
    -rw-r--r-- 1 root root    66 Feb  4 10:02 files/index.html

    # cat files/index.html
    This is a homepage created for ansible roles.

    Next, update handlers/main.yml as follows:

    # cat handlers/main.yml

    # handlers file for apache-role
    - name: restart apache
      service: name=httpd state=restarted


  3. Writing Inspec tests

    In this step, we write tests to check if apache is installed and configured on the server. For this, create a default_test.rb

    # vi test/integration/default/default_test.rb

    describe package('httpd') do
      it { should be_installed }

    describe file('/etc/httpd/conf/httpd.conf') do
      it { should exist }
      its('owner') { should cmp 'root' }

    describe file('/var/www/html') do
      it { should exist }
      its('owner') { should cmp 'root' }

    describe service('httpd') do
      it { should be_installed }
      it { should be_enabled }
      it { should be_running }


  4. Setup kitchen configuration file

    In this step, we write a kitchen.yml to be able to perform kitchen test. Create a .kitchen.yml file in the directory as follows:

    $ vi .kitchen.yml

      name: vagrant
        audio: none

      hosts: test-kitchen
      name: ansible_playbook
      require_chef_for_busser: false
      require_ruby_for_busser: false
      ansible_verbosity: 2
      ansible_verbose: true
      role_path: test/integration/default/roles

      - name: wittman/centos-7.2-ansible

      name: inspec

      - name: default
            - test/integration/default

    Explaining the kitchen.yml sections:

    • driver: This is where we configure the Kitchen Driver, in our case we are using kitchen-vagrant. This is the component that will create the machine that we will use to test our role.
    • platforms: This is a list of operation systems that we want to test our code on, and it relates to the driver config.
    • provisioner: The provisioner is the component that configures, or “converges”, the machine. In our case we’ll be using the ansible_playbook provisioner, since it’s the ability of our Ansible playbook to configure a server that we’re interested in actually testing.
    • verifier: The verifier is the test runner, and we will be using Inspec plugin.
    • suites: This section defines what we want to test. Here we can define a matrix of test suites to run.
  5. Execute kitchen test

    To execute kitchen tests, run `kitchen test`. You should see the following output:

    $ kitchen test

    ... <A lot of lines will preced this>

    Target:  ssh://vagrant@

      System Package httpd
         ✔  should be installed
      File /etc/httpd/conf/httpd.conf
         ✔  should exist
         ✔  owner should cmp == "root"
      File /var/www/html
         ✔  should exist
         ✔  owner should cmp == "root"
      Service httpd
         ✔  should be installed
         ✔  should be enabled
         ✔  should be running

    Test Summary: 8 successful, 0 failures, 0 skipped

           Finished verifying <default-wittman-centos-72-ansible> (0m1.75s).
    -----> Destroying <default-wittman-centos-72-ansible>...
           ==> default: Forcing shutdown of VM...
           ==> default: Destroying VM and associated drives...
           Vagrant instance <default-wittman-centos-72-ansible> destroyed.
           Finished destroying <default-wittman-centos-72-ansible> (0m4.44s).
           Finished testing <default-wittman-centos-72-ansible> (2m18.44s).
    -----> Kitchen is finished. (2m20.82s)


  6. Conclusion

    You now have a foundation for testing your Ansible roles, which allows you to test your roles/playbooks before running on a live server.

1 comment on"Test Ansible Roles with Inspec"

  1. Hi, I’m a fellow IBMer from GBS and I found this article fascinating, many thanks for sharing.
    I’ve invited you to our #infra-testing Slack channel in the ‘IGNITE Quality & Test’ workspace,
    as I’m confident that other GBS testers might like to learn more about things like this 🙂

Join The Discussion