0

Testing Ansible roles with Molecule

Introduction

In this article, I will demonstrate how to install Molecule on Ubuntu 18.04 server and how to test an ansible role using molecule.

The molecule is developed to test the Ansible role with the different environments. Molecule provides support for testing with multiple instances, operating systems and distributions, virtualization providers, test frameworks and testing scenarios.

Normally when I need to test the ansible roles, create vagrant machines with different Distributions and destroy once the testing is completed. Molecule helps to reduce the time in testing as distributions are created as per the configuration files and we can include test cases also with the Molecule.

Prerequisites

pip is the only supported installation method.

It is highly recommended that you install molecule in a virtual environment. This will provide a modern copy of setuptools which is mandatory in order for molecule to be installed successfully and function correctly. If you cannot use a virtual environment then you can attempt a package upgrade with the following:
$ pip install --upgrade --user setuptools
  • One Ubuntu 18.04 server.
  • Docker installed on your server. 
  • Python and ansible installed. (Ansible will be installed automatically as a dependency of the molecule)

Installation

$ sudo apt-get update
$ sudo apt-get install -y python-pip libssl-dev

Create a new virtual environment

$ python3 -m venv molecule

Activate it to ensure that your actions are restricted to that environment:

$ source molecule/bin/activate

Next, in your activated environment, install the wheel package, which provides the bdist_wheel setuptools extension that pip uses to install Ansible:

(molecule) jjames@test:~$ python3 -m pip install wheel

You can now install molecule and docker with pip. Ansible will be automatically installed as a dependency for Molecule:

(molecule) jjames@test:~$ python3 -m pip install molecule docker

Docker: This Python library is used by Molecule to interface with Docker. You will need this if you are using Docker as a driver.

Inspecting Molecule folder

(molecule) jjames@test:apche2$ ll molecule/default
total 32
-rw-r--r--  1 jjames  1445295183   1.1K Jan  1 22:44 Dockerfile.j2
-rw-r--r--  1 jjames  1445295183   555B Jan  1 22:44 INSTALL.rst
-rw-r--r--  1 jjames  1445295183   240B Jan  1 22:44 molecule.yml
-rw-r--r--  1 jjames  1445295183    63B Jan  1 22:44 playbook.yml
drwxr-xr-x  4 jjames  1445295183   128B Jan  1 22:44 tests
  • Since Docker is the default Driver, we find a Dockerfile.j2 Jinja2 template file in place. Molecule will use this file to build a docker image to test your role against.
  • INSTALL.rst contains instructions on what additional software or setup steps you will need to take in order to allow Molecule to successfully interface with the driver.
  • molecule.yml is the central configuration entry point for Molecule. With this file, you can configure each tool that Molecule will employ when testing your role.
  • playbook.yml is the playbook file that contains the call site for your role. Molecule will invoke this playbook with ansible-playbook and run it against an instance created by the driver.
  • tests is the tests directory created because Molecule uses TestInfra as the default Verifier. This allows you to write specific tests against the state of the container after your role has finished executing. Other verifier tools are available.

Creating a Role with Molecule

To generate a new role with Molecule, simply run:

(molecule) jjames@test:~$ molecule init role -r apache2 -d docker

The -r flag specifies the name of the role while -d specifies the driver, which provisions the docker hosts for testing

(molecule) jjames@test:~$ cd apache2 && ll
total 8
-rw-r--r--  1 jjames  1445295183   1.3K Jan  1 22:44 README.md
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 defaults
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 handlers
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 meta
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 molecule
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 tasks
drwxr-xr-x  3 jjames  1445295183    96B Jan  1 22:44 vars

Molecule created the necessary folder structure for the Ansible role. You can see a folder called molecule, which contains all the necessary files for the molecule to create the test environment test the role. We will look into it later. Let’s test everything is working correctly by running.

(molecule) jjames@test:apache2$ molecule test

Molecule prints this test matrix, which specifies the order of test actions:

--> Validating schema /home/jjames/apache2/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix

└── default
    ├── lint
    ├── dependency
    ├── cleanup
    ├── destroy
    ├── syntax
    ├── create
    ├── prepare
    ├── converge
    ├── idempotence
    ├── side_effect
    ├── verify
    ├── cleanup
    └── destroy

--> Scenario: 'default'
--> Action: 'lint'

...............
...............
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
--> Pruning extra files from scenario ephemeral directory

For example, the PLAY_RECAP for the default 'create' action should look like this:

Let’s try configuring apache2 role and test

Configuring Apache2

Create the apach2 installation and configuration ansible role

(molecule) jjames@test:apache2$ vim tasks/main.yml
---
- name: "Ensure packages are Installed"
  yum:
    name: "{{ apache2_packages }}"
    state: present

- name: "Ensure {{ service_name }} service is started and enabled"
  service:
    name: "{{ item }}"
    state: started
    enabled: true
  with_items: "{{ service_name }}"

Save and close the file when you are finished. and declare the variables

(molecule) jjames@test:apache2$ vim defaults/main.yml
---
apache2_packages:
  - apache2

service_name:
  - apache2

Save and close.

You have created the necessary files and configurations for the apache2 role. now let’s check and update the test infrastructure configuration in the Molecule folder.

(molecule) jjames@test:apache2$cd vim molecule/default/molecule.yml
---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
platforms:
  - name: instance
    image: ubuntu:18.04
provisioner:
  name: ansible
  lint:
    name: ansible-lint
verifier:
  name: testinfra
  lint:
    name: flake8

Check and update the platforms section as per your requirements. You can add multiple instances also for testing. Save and quit.

Run Test

Now that you’ve successfully configured the test environment, Run Molecule test from the role folder.

(molecule) jjames@test:apache2$ molecule test

You can see from CLI that Molecule is creating an environment and running the tests. we haven’t written any test cases, but we will cover that in another post.

If the test is a success, you can see the output similar to below.

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Notes:
If you run molecule test, it will create the environemnt and go thorugh each steps and destroy the environemnt. if you dont't want to run the complete test, and only requited to verify that role is functioning correctly, run molecule converge, which will not destroy the environment and it is pretty fast compared with molecule test.

Molecule converge test matrix limited to

--> Test matrix

└── default
    ├── dependency
    ├── create
    ├── prepare
    └── converge

--> Scenario: 'default'
--> Action: 'dependency'

Reference:

https://github.com/ansible/molecule

https://molecule.readthedocs.io/

Check out these books from amazon


Leave a Reply