Infrastructure testing provides some challenges just because of the mere fact you are building machines and not just compiling code. To test Ansible, I used to run Ansible with --syntax-check
and --list-tasks
. For roles I would run local tests with Vagrant using the tests/ directory in the role. The tests had Ansible test itself with the uri module or other checks. This is ok for simple checks but can be cumbersome and time consuming as it doesn’t catch everything.
Molecule has made this very simple. Install Molecule with pip install molecule. Create your role with molecule init --role-name role --driver-name driver
. The current drivers are Docker, OpenStack, Vagrant, EC2, GCE, LXC, LXD, and a few others with Docker being the default. It’s not absolutely required to build the role with molecule init but it adds the molecule dir with default testing and the .yamllint file.
Rather than rewrite their documentation, I’ll just go through what I have set up to test my roles. Currently I’m using the Vagrant driver with a CentOS 7 box ( I don’t do much with non RHEL distros) and the libvirt provider for Vagrant. So here’s what my molecule/molecule.yml file looks like:
---
dependency:
name: galaxy
driver:
name: vagrant
provider:
name: libvirt
lint:
name: yamllint
platforms:
- name: bind
box: centos/7
provisioner:
name: ansible
lint:
name: ansible-lint
scenario:
name: default
verifier:
name: testinfra
options:
sudo: True
lint:
name: flake8
Molecule also uses testinfra to run automated tests against the Vagrant box. Here’s a simple example to check a firewalld role:
import os
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
def test_firewall_installed(host):
package = host.package("firewalld")
assert package.is_installed
def test_firewall_service(host):
service = host.service("firewalld")
assert service.is_running
assert service.is_enabled
def test_firewall_config(host):
config = host.file("/etc/firewalld/zones/public.xml")
assert config.exists
assert config.contains('<service name="http"/>')
assert config.contains('<service name="https"/>')
assert config.contains('<service name="ssh"/>')
Testinfra will check that the package firewalld is installed, the service is running and enabled, and that the /etc/firewalld/zones/public.xml file contains the services defined.
To start your molecule testing you can run molecule test.
Here’s a video running this setup against a firewalld role: