Integration testing using Ansible and Test Kitchen
Introduction
I recently wrote a master-slave BIND 9 solution using Ansible and in this post I describe a multi-node integration testing approach for the solution using Test Kitchen and Neill Turner‘s Kitchen-Ansible extensions.
To be sure, Test Kitchen lacks proper support for multi-node integration testing, and its maintainers have explained the reasons for the lack of multi-node support in this thread here. Suffice to say, Puppet’s Beaker had multi-node support some five or six years ago, as did Puppet’s earlier, now retired, Rspec-system project.
This lack of multi-node support is, indeed, a quite serious limitation in an otherwise excellent framework. I am encouraged that the team has an issue open to track adding multi-node support here.
General approach
The aforementioned limitation aside, it is still possible to do rudimentary integration testing, as long as we tolerate a few manual steps and design our tests so that all testing on the first node can be completed before testing on the subsequent nodes begins.
In the case of my BIND 9 solution, this means that I’ll write one test suite for the DNS master, a second suite for the first DNS slave, and a third suite for the second DNS slave. The first suite will prove that the DNS master has the BIND 9 packages installed, zone files and other files in place, that the BIND 9 service runs, and that name resolution works. The second suite will prove that a DNS slave is build, and receives a zone transfer as soon as it comes online. The third suite simply proves that more than one DNS slave can be handled by the solution.
The approach would fall short if we had a requirement, say, to add a new DNS record after the master was created, update its serial number, and see that all the slaves received the update. But as I say, it’s a lot better than nothing.
I must acknowledge Maxim Chernyak for documenting the Kitchen hack that this work is based on.
BIND 9 solution
The Ansible role that we will be testing configures a simple BIND 9 system with a single master that is also a master for all of its zones, and one or more slaves that receive the zone tranfers and respond to recursive DNS queries.
The following figure shows the high-level architecture:
Ansible role
The code for this solution is available online at Github here. It’s not my intention here to discuss the Ansible code itself, except where it is relevant to the integration testing procedure.
Kitchen config
To learn more about my Kitchen config, please see my earlier post where I described the general config.
The .kitchen.yml file
The .kitchen.yml
I have for the role is as follows:
--- driver: name: vagrant platforms: - name: centos-7.2 driver_plugin: vagrant driver_config: box: puppetlabs/centos-7.2-64-nocm provisioner: name: ansible_playbook hosts: test-kitchen ansible_verbose: false ansible_verbosity: 2 require_ansible_repo: false require_ansible_omnibus: true require_chef_for_busser: false verifier: name: serverspec bundler_path: '/usr/local/bin' rspec_path: '/usr/local/bin' suites: - name: master verifier: patterns: - roles/ansible-bind/test/integration/master/serverspec/master_spec.rb driver_config: network: - ['private_network', {ip: '10.0.0.10'}] - name: slave1 verifier: patterns: - roles/ansible-bind/test/integration/slave1/serverspec/slave1_spec.rb driver_config: network: - ['private_network', {ip: '10.0.0.11'}] - name: slave2 verifier: patterns: - roles/ansible-bind/test/integration/slave2/serverspec/slave2_spec.rb driver_config: network: - ['private_network', {ip: '10.0.0.12'}]
Recent Comments