Testing Ansible Playbooks/roles with Test-kitchen and Serverspec

In this post, I will discuss the tools/plugins to test the playbooks/roles as part of infrastructure testing through TDD( Test Driven Development).

We used test-kitchen and serverspec to test the playbook

1- make sure on your work station you have installed git,docker,ruby,

install the rpm- ruby package manger and install bundler usig rpm.

create a file called Gemfile and enter the below content and run

vim Gemfile
source ‘https://rubygems.org'
gem ‘test-kitchen’, ‘~> 1.8.0’
gem ‘kitchen-docker’
gem ‘kitchen-ansible’
gem ‘net-ssh’
gem ‘serverspec’
gem ‘kitchen-verifier-serverspec’
[root-testmachine:]bundle install

we have installed the gems ‘test-kitchen’ , ‘kitchen-docker’,’serverspec’, ‘kitchen-ansible’ and ‘net-ssh’ with the above step.

create a file called .kitchen.yml file and add the below entries

---
driver:
name: docker
#enble to true if you are not s root on your workstation
use_sudo: false

platforms:
- name: ubuntu-14.04
driver:
image: rndmh3ro/docker-ubuntu1404-ansible:latest
platform: ubuntu


provisioner:
name: ansible_playbook
hosts: test-kitchen
roles_path: roles
ansible_verbose: false
ansible_verbosity: 2
require_ansible_repo: false
require_ansible_omnibus: false
require_chef_for_busser: false
ansible_connection: ssh


verifier:
name: serverspec
use_sudo: yes
sudo_path: true

suites:
- name: default
verifier:
default_pattern: true
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
env_vars:
TARGET_HOST: 127.0.0.1
SUDO: true

as we are using docker as the virtualization emulator in our scenario, we gave name: docker in the driver section.

Next steps is to specify the platforms , as i wish to run and test my playbook in a ubuntu server platform we have specifed as and found an docker image that has ansible installed along with it.

platforms:
- name: ubuntu-14.04
driver:
image: rndmh3ro/docker-ubuntu1404-ansible:latest
platform: ubuntu

Next step is to mention the provisioner whether it is ansible/puppet/chef and the desired paths for playbooks/roles to look for it.

provisioner:
#nameof proviosner ansible-if notfound
name: ansible_playbook
#name of host it has to run,can localhost
hosts: test-kitchen
#path for ansible roles
roles_path: roles
ansible_verbose: false
ansible_verbosity: 2
require_ansible_repo: false
#notinstall ansible(true -viceversa)
require_ansible_omnibus: false
#don't install chef - should be false everytime
require_chef_for_busser: false
ansible_connection: ssh

Next step is to mention the verifier — tool/framework to perform the test.

we prefered to use serverspec, as it has mostly plain English kind of language we can also use cucumber,inspec and rspec and other frame works.

verifier:
name: serverspec
use_sudo: yes
sudo_path: true

next step is to define the path for the test cases and suites.

name is very important ,by default test-kitchen looks for the default location of test/integration/<suitename>/serverspec/<suitename>_spec.rb file , unless you specify the pattern of the test case file.(I have used default patern in my example)

suites:
- name: default
verifier:
default_pattern: true
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
env_vars:
TARGET_HOST: 127.0.0.1
SUDO: true

My directory/project strcture is like

/opt/ansible/ansible-kitchen:

│ default.yml
│ .kitchen
│ .kitchen.yml
│ Gemfile
│ Gemfile.lock
├── roles
│ └── splunk
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── spec
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ ├── tests
│ └── vars
├── spec
│ ──spec_helper.rb
├── test
│ └── integration
│ └── default
│ │ ├── serverspec
│ │ ├── spec_helper.rb
│ │ └── test_spec.rb
│ ── default.yml
└── vendor

test-kitchen commands:

kitchen create — it just create the docker conatiner/vm to run

kitchen destroy- it will delete the conatiners/vm’s created by kitchen.

kitchen converge: will run the playbooks and roles as mentioned in provision

kitchen verify: will test the playbooks and roles as mentioned in the suites.

kitche test : will create,converge,verify and destroy the containers.