Using Molecule and Docker to test Ansible Playbooks

Martin Reinhardt
Jun 20, 2019 · 3 min read
Image for post
Image for post

In the DevOps lifecycle, configuration management has always been an integral part of maintaining the desired system state. Many common tools such as Chef, Puppet, Ansible, SaltStack were used for configuration management. But before the configuration can be used in production, it has to be tested because different systems behave differently with the same configuration. So we have to be aware that our desired configuration state goes through every test scenario before it is applied to production. This is where Molecule comes into play.

Molecule has been specially developed for testing Ansible Reels under various operating systems. It uses the Ansible Playbook to determine which Ansible role to test. Molecule uses Serverspec, Testinfra and Goss as Verifier backend. To learn more about Molecule, click here. Molecule supports multiple backends such as Vagrant, Docker and OpenStack. With Molecule you can use Serverspec (Like Test Kitchen) but also ‘Testinfra’. Like Serverspec, Testinfra is a tool for writing unit tests, but it is written in Python.

To get started with Molecule just install it as python library, along with docker:

pip install ansible molecule docker

Voilà, it’s installed. With the installation of Molecule Testinfra is installed. For reference I use my docker-hardening role in the further steps. If you want to create a new Ansible role from scratch Molecule can help you here:

molecule init --driver docker --role role_name

In both examples the source code already contains a folder called molecule. All tests and docker configurations can be found here. The Molecule configuration is located in the molecule/default/molecule.ymlfile file:

driver:
name: docker
lint:
name: yamllint

The interesting part is that we use for this example docker as backend driver and also linting our YAML files with yamllint. To configure docker Molecule will generate an Docker image with the help of a template and start it:

platforms:
- name: instance
image: debian:9
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- /sys/fs/cgroup:/sys/fs/cgroup:ro
command: /sbin/init
capabilities:
- SYS_ADMIN
exposed_ports:
- 80/udp
- 80/tcp
published_ports:
- 0.0.0.0:8888:80/udp
- 0.0.0.0:8888:80/tcp
groups:
- debian

The important thing here is the privileged and capabilities part: To use a systemd unit in Docker you need this. Therefore, we need to adjust the docker configuration to run the system in docker containers. This configuration consists of approving the container core to:

Remember that these docking images may only be used in test environments and not in production.

If you run molecule test, Molecule normally runs in the following sequence:

Molecule will run a number of tests, either the default values like linting, idempotence etc., all of which are configurable under the configuration file molecule.yml for each scenario.
After completion of the tests, the Molecule destroys the container named instance-to-test-ansible, as described in the configuration.

It’s quite handy, but in case of debugging failing tests it may be annoying to create the setup again. So in this case you can use molecule test --destroy=never, which leads to skipping the last destroy step.

When it comes to the structure of different Molecule “playbooks” I recommend the following structure:

But that’s just the basic stuff. You can add test folders under molecule/default and add pytest testcases there. Here testinfra can be used:

import os 
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
def test_docker(host):
daemon = host.service("docker")
assert daemon.is_running
assert daemon.is_enabled

It provides access to the provisioned Ansible machine and allows the verification of the automation scripts, e.g. check if daemon is running on a certain network interface.

I hope you like this little introduction into testing Ansible playbooks with Molecule. You can also use Molecule to engineer your playbooks in TDD-style…

Holisticon Consultants

voices of holistikoenner/innen

Martin Reinhardt

Written by

IT Architect from Hamburg

Holisticon Consultants

Promise! We listen attentively. We understand. And we do what we’re best at: honest technological and methodical management and IT consulting. Every day. With passion and talent. And the best people that we can find.

Martin Reinhardt

Written by

IT Architect from Hamburg

Holisticon Consultants

Promise! We listen attentively. We understand. And we do what we’re best at: honest technological and methodical management and IT consulting. Every day. With passion and talent. And the best people that we can find.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store