Netresearch Blog

Blog

Our blog contains all news and insights. We make our knowledge available, give tips, and inform you about everything that happens inside and outside our company.

How Ansible, Molecule and Vagrant are revolutionizing testing

Re-touching finished IT infrastructures or developed IT products can be associated with a certain risk: Possible errors can be the result if something is changed again afterwards. Since updates or corrections always mean a change again, it would be helpful at this point to have a tool for testing changes. After all, testing is an essential part of any development process, but any 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 that deploy 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

It's important to note that when testing roles that deploy Docker containers, it can be difficult to do so in a containerized environment (Docker in Docker, for example in GitLab CI). To overcome this issue, we can test our roles in VMs instead. In order to control these VMs, we will need a certain Molecule plugin called molecule-vagrant. This plugin fully takes care of setting up isolated environments.

Step-by-Step Guide to Testing Ansible Roles with Molecule and Vagrant

Prerequisites:
 Ansible
 Vagrant and VirtualBox
 Molecule and Molecule-Vagrant

Step 1: Initialize a new scenario with Molecule

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

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

Step 2: Configure your role’s dependencies

To automate Ansible role testing with Vagrant and Molecule, first, we have to configure the VM image for the Vagrant "box." inside of the molecule.yml file. We are going to be using 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

Then we can configure the role's dependencies by creating a requirements.yml file for Molecule testing. This file should list all the dependencies, including any Ansible roles, modules, or libraries that need to be installed.

Finally, you should create a prepare.yml file that sets up the dependencies specified in the requirements.yml file. This file can include tasks such as installing necessary packages, configuring the environment, or running any necessary scripts. With these steps in place, you can be sure that your 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: Test your role

Once you have configured your role's dependencies, you can run the command molecule create to create the VM and prepare it. This command will create an isolated environment for testing your role and install all the dependencies specified in the requirements.yml file.

After the VM is created, you can use the command molecule login to log in to the VM and check the installation of your role's dependencies. This will give you a chance to verify that everything has been set up correctly before moving on to the next step.

Next, you can use the command molecule converge to deploy your role in the isolated environment. Keep in mind that you will have to adjust the converge.yml to run the playbook as root. This step will ensure that your 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 make sure that the installation and functionality of your role is working as expected, you can write some tests in the verify.yml file and then run those with the command molecule verify. This step will give you the confidence that your role is working correctly before deploying it to production.

$ 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, you can run the command molecule destroy to delete the VMs that we just created. This step will remove all the resources that were used during the testing process, making sure to keep everything clean.

Bonus: Linting Your Files with Molecule

Bonus: Linting Your Files with Molecule

Molecule can even lint your files, if you configure it! Add this to your molecule.yml:

$ 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

Congratulations, you have just set up Molecule in a project.

You can now run molecule test which will run all of the steps below and also check for idempotency. You can find our demo here:
 Molecule Docker Demo (Github, Netresearch)

CI/CD

GitLab CI integration is also quite easy, as it simply requires running molecule test which does all of the above steps automatically. By automating the process, we save even more time and can ensure that our roles are always working as intended.

CI Configuration

$ 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 benefits of using Molecule for testing ansible roles are many. For one, the setup is both easy and fast. Additionally, we save a lot of time by not having 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, Ansible testing has never been easier

Share article:
Related topics
Technologies

New Blogposts

Continous Testing: Molecule und Vagrant

By Sebastian Mendel genannt Mendelsohn

How Ansible, Molecule and Vagrant are revolutionizing testing

Make Ansible automations testable and detect deployment errors earlier? Discover how to automate…

Read more
Netresearch: TYPO3 Developer Days Karlsruhe 2022
By Tobias Hein

Netresearch war dieses Jahr mit zwei Pro-Sessions bei den TYPO3 Developer Days in Karlsruhe…

Read more
20 years of AIDA customer relationship
By Caroline Kindervater

Communication, expertise and trust play a major role in the successful implementation of customer…

Read more
Livegang SSO-Anbindung with Keycloak for Lehrerwelt
By Thomas Schöne

For our customer AAP Lehrerwelt GmbH, which is part of the Klett Group, we implemented a…

Read more