Netresearch Blog

Blog

You can find all the news and insights here. We share our knowledge, give tips and inform you about everything that happens internally and externally at our company.

How Ansible, Molecule and Vagrant are revolutionizing testing

Touching finished IT infrastructures or developed IT products again can be associated with a certain risk: Possible errors can be the result if something is changed again afterwards. As updates or corrections always mean a change, it would be helpful at this point to have a tool for testing changes. Because testing is an essential part of every development process, but every beginning can be difficult. Molecule, a tool for testing Ansible roles, can simplify this process. This guide walks through the process of testing roles with Molecule, including setting up test environments, deploying roles, and testing deployed devices.

It covers a specific case of testing roles deploying Docker containers and how to overcome the challenges involved.

By the end of this guide, you should have a solid understanding of how to use Molecule to test Ansible roles and ensure they work as expected before deploying them to production.

Testing Ansible roles with Docker containers

When testing roles that deploy Docker containers, it can be difficult to do this in a containerised environment (Docker in Docker, for example in GitLab CI). To work around this problem, we can test our roles in VMs instead. To manage these VMs, we need a specific Molecule plugin called molecule-vagrant. This plugin completely takes care of setting up isolated environments.

Guide to testing Ansible roles with Molecule and Vagrant

Prerequisites:
Ansible
Vagrant and VirtualBox
Molecule and Molecule-Vagrant plugin

Step 1: Initialising a new scenario with Molecule

$ molecule init scenario -d vagrant
INFO Initialising new scenario default...
INFO Initialised scenario in /home/sebastian/a/molecule/default successfully.

https://github.com/netresearch/molecule_http_docker_demo/commit/815209ddac9a9523107ee5032574107ff034583e

Step 2: Configuring the dependencies

To automate the testing of Ansible roles with Vagrant and Molecule, we first need to configure the VM image for the Vagrant "box" in the molecule.yml file. We will use Debian.

$ git diff 729d4e3d
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -1,11 +1,16 @@
 ---
 dependency:
   name: galaxy
 driver:
   name: vagrant
 platforms:
   - name: instance
+ box: debian/bullseye64
provisioner:
   name: ansible
 verifier:
   name: ansible

https://github.com/netresearch/molecule_http_docker_demo/commit/729d4e3de51cdcf91dabcf252b2cdf306b7d9dd6

We can then configure the role's dependencies by creating a requirements.yml file for Molecule. This file should list all dependencies, including any Ansible roles, modules or libraries that need to be installed.
Finally, a prepare.yml file must be created that sets up the dependencies specified in the requirements.yml. This file can include tasks such as installing required packages, configuring the environment or running required scripts. These steps ensure that the role's dependencies are properly configured and ready for testing.

$ git diff ac65d0dc
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -1,6 +1,7 @@
 ---
 dependency:
   name: galaxy
+ requirements-file: requirements.yml
 
 driver:
   name: vagrant

--- /dev/null +++ b/molecule/default/prepare.yml @@ -0,0 +1,19 @@ +--- +# Add necessary requirements to the test environment +- name: Prepare + hosts: all + # These roles need root access + become: true + + vars: + pip_install_packages: + - name: docker + + roles: + - geerlingguy.docker + - geerlingguy.pip + + pre_tasks: + - name: Update apt cache + ansible.builtin.apt: + update_cache: true
--- /dev/null +++ b/molecule/default/requirements.yml @@ -0,0 +1,8 @@ +--- +# Our role needs Docker and pip to be installed +roles: + - src: geerlingguy.docker + version: 6.0.4 + + - src: geerlingguy.pip + version: 2.2.0

https://github.com/netresearch/molecule_http_docker_demo/commit/ac65d0dc012f1483ba1ab726f510ba03d4a09ff1

Step 3: Testing the role

Once the dependencies of the role are configured, we can run the molecule create command to create and prepare the VM. This command creates an isolated environment to test the role and installs all the dependencies specified in the requirements.yml file.

Once the VM has been created, we can use the molecule login command to log into the VM and manually check the installation of the dependencies. This allows us to verify that everything has been set up correctly before proceeding to the next step.

We then use the molecule converge command to deploy the role in the isolated environment. It is important to remember that the converge.yml is customised to run this playbook as an authorised user (in this case as root). This step ensures that the role is properly installed and configured on the test VM.

$ git diff 74fdd3cb
--- a/molecule/default/converge.yml
+++ b/molecule/default/converge.yml
@@ -1,6 +1,8 @@
 ---
 - name: Converge
   hosts: all
+ # Docker access needs root permissions
+ become: true
   tasks:
     - name: "Include molecule_http_docker_demo"
       ansible.builtin.include_role:

--- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -12,6 +12,9 @@ platforms: provisioner: name: ansible + options: + # Enable `--diff` mode + D: true verifier: name: ansible

https://github.com/netresearch/molecule_http_docker_demo/commit/74fdd3cb17da045ff0f874400d8a0abf928f260f

To ensure that the installation and functionality of the role works as expected, we can define tests in the verify.yml file and then execute them with the molecule verify command. This step gives us the certainty that the role is working correctly.

$ git diff 74fdd3cb
--- a/molecule/default/verify.yml
+++ b/molecule/default/verify.yml
@@ -3,8 +3,36 @@
 
 - name: Verify
   hosts: all
+ become: true
   gather_facts: false
   tasks:
- name: Example assertion
+ - name: Register Docker container status
+ community.docker.docker_container_info:
+ name: nginx
+ register: container_info
+
+ - name: Nginx Docker container assertion
     ansible.builtin.assert:
- that: true
+ that:
+ - "container_info.exists"
+ - "container_info.container.State.Status == 'running'"
+ - "container_info.container.State.Running"
+ success_msg: "container OK"
+ fail_msg: "container NOT OK"
+
+ - name: Make a simple HTTP request
+ ansible.builtin.uri:
+ url: http://localhost:80
+ return_content: true
+ register: result
+
+ - name: HTTP request assertion
+ ansible.builtin.assert:
+ that:
+ - "result.status == 200"
+ success_msg: "HTTP request OK"
+ fail_msg: "HTTP request NOT OK"
+
+ - name: Print HTTP response
+ ansible.builtin.debug:
+ msg: "{{ result.content }}"

https://github.com/netresearch/molecule_http_docker_demo/commit/74fdd3cb17da045ff0f874400d8a0abf928f260f

Finally, we can use the molecule destroy command to delete the VMs that have just been created. This step removes all resources that were used during the test process.

Bonus: Linting the role with Molecule

Molecule also has the ability to check files in the role according to certain rules(linting)! To do this, the configuration must be adjusted as described below:

$ git diff 74fdd3cb
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -18.3 +18.8 @@ provisioner:
 
 verifier:
   name: ansible
+
+lint: |
+ set -e
+ yamllint .
+ ansible-lint

--- a/tasks/main.yml +++ b/tasks/main.yml @@ -6,7 +6,7 @@ source: pull force_source: true -- name: Start start nginx service via Docker +- name: Start start nginx service via Docker # noqa args[module] community.general.docker_container: name: "{{ nginx_service_name }}" image: "{{ nginx_image }}"

https://github.com/netresearch/molecule_http_docker_demo/commit/74fdd3cb17da045ff0f874400d8a0abf928f260f

To execute all steps at once and additionally check for idempotency, only the command molecule test is necessary

A simple but complete demo can be found here:
Molecule Docker Demo (Github, Netresearch)

$ cat .gitlab-ci.yml
---
stages:
  - test

test:
  stage: test
  tags:
    - molecule
  script:
    - molecule test -- --extra-vars "docker_registry_username=${CI_REGISTRY_USER}" --extra-vars "docker_registry_password=${CI_REGISTRY_PASSWORD}"

The advantages of using Molecule to test Ansible roles are manifold. Firstly, it is quick and easy to set up. We also save a lot of time as we don't have to set up isolated environments. We can set up controlled environments in a VM with Vagrant (controlled by the molecule-vagrant plugin) and deploy and test roles with Molecule.

With the help of Molecule and Vagrant, testing with Ansible has never been easier.

Share article:
Related topics
Technologies

Latest posts

Header image for the Netresearch blog article: Orange background with the text "Public Interest Technology: TYPO3 now officially recognized as a Digital Public Good." On the right side, a graphic depiction of a stylized globe surrounded by interconnected people – symbolizing global, public good–oriented digitalization.

By Franka Hesse

Public good technology: TYPO3 now officially recognised as Digital Public Good

The Digital Public Goods Alliance has officially recognised TYPO3 as a digital public good. We…

Read more
Netresearch blog article image: “From the Classroom to the Dev Team: School Internship at Netresearch” – background shows a black-and-white comic-style drawing of two boys looking at a computer screen with visible code.
By Franka Hesse

What does a student internship look like that really inspires - and where you don't just watch, but…

Read more
Netresearch blog article image: “Send newsletters directly from TYPO3 – New integration of Universal Messenger into TYPO3”, with blurred letters in the background symbolizing digital communication.
By Franka Hesse

With our new TYPO3 extension, the Universal Messenger is seamlessly integrated - a milestone for the…

Read more
Netresearch blog article image: “Sustainable Software Development: Those Who Don’t Think Ahead Today Will Pay the Price Tomorrow” – background shows a computer keyboard with a small green seedling sprouting from it, symbolising growth and sustainability in tech.
By Thomas Schöne

Sustainable software development is a competitive advantage for B2B companies. Lower costs, less…

Read more