\ /
Ansible  Automation 

Setting up Molecule for Testing Ansible Roles with Vagrant and Testinfra

Introduction

Molecule is a tool designed for testing Ansible roles. Molecule provides support for testing with multiple instances, operating systems and distributions, virtualization providers, test frameworks and testing scenarios. You can easily run your tests in virtual environments locally and in the cloud.

Molecule uses a driver to delegate the task of creating instances and carry out the execution of the role inside the instance. The instance is launched automatically and destroyed by the driver once the role is executed and tested. Before testing a role in a production environment, it is recommended to test it with Molecule.

Molecule has different components that have to be configured:

  • The Dependency manager: Molecule uses galaxy by default to resolve your role dependencies.

  • The Driver provider: Molecule uses the driver to delegate the task of creating instances. Molecule uses Docker by default, but we can use Vagrant with VirtualBox as the provider if we want to work with virtual machines (VMs).

  • The Lint command: Molecule can call external commands to ensure that best practices are encouraged. We can use yamlint and ansible-lint.

  • The Platforms definitions: Molecule relies on this to know which instances to create, name and to which group each instance belongs. If we use Vagrant, we have to specify the Vagrant box to be used together with the VM settings (memory, CPUs and networking).

  • The Provisioner: Molecule only provides an Ansible provisioner. Ansible manages the life cycle of the instance based on this configuration.

  • The Scenario definition: Molecule relies on this configuration to control the scenario sequence order.

  • The Verifier framework: Molecule uses Ansible by default to provide a way to write specific state checking tests on the target instance, although we can use Testinfra, which is used for writing and executing unit tests in Python.

Prerequisites

The packages installation and configuration along with the execution of Ansible and Molecule have been carried out in Ubuntu 20.04. To get started you’ll need to have python and pip installed. As the Ansible version used is 2.9, python 3 is required. The following tools and packages have to be installed to make everything work:

  • VirtualBox: Creates the VMs used for testing the roles.
    sudo dpkg -i virtualbox-6.1_6.1.12-139181_Ubuntu_eoan_amd64.deb
  • Vagrant: Orchestrates VirtualBox and automatically deploys and destroys the VMs.
    sudo dpkg -i vagrant_2.2.9_x86_64.deb 
    sudo apt-get install -f
  • Molecule: Testing Ansible roles.
    python3 -m pip install --user "molecule[lint]"
  • Molecule Vagrant plugin: Designed to allow the use of Vagrant for provisioning of test resources.
    pip3 install --user molecule-vagrant
  • Testinfra: Write unit tests in Python to test actual state of the servers configured by Ansible. Used to test the role functionalities in the VM created by Vagrant and VirtualBox.
    pip3 install testinfra

Could be necessary to disable UEFI Secure Boot to make VirtualBox work.

How it works

The first step to test an Ansible role is to initiate a new scenario for use with Molecule. To do this we have to get inside the role directory and execute the following command:

molecule init scenario

This will create a molecule directory. Inside the molecule directory there is a default directory that represents the default testing scenario created by Molecule, although we can create more scenarios with different configurations. A scenario defines what will be performed when we run molecule. The default scenario follows this execution sequence:

  1. dependency: Pull dependencies from ansible-galaxy if the role requires them.
  2. lint: Check all the YAML files with yamllint.
  3. cleanup: Executes the cleanup.yml playbook if exists.
  4. destroy: If there is a VM with the same name running, destroy it.
  5. syntax: Check the role with ansible-lint.
  6. create: Create the VM.
  7. prepare: Executes the prepare.yml playbook, which brings the host to a specific state.
  8. converge: Executes the converge.yml playbook, which runs the role.
  9. idempotence: Molecule runs the playbook a second time to check for idempotence.
  10. verify: Run the tests defined in the tests directory.
  11. cleanup: Executes the cleanup.yml playbook if exists.
  12. destroy: Destroy the VM.

The following files are provided for Molecule testing configuration:

  • molecule/default/molecule.yml: Contains the definition of the platform driver (Vagrant) and the provider (VirtualBox), the VM OS settings, the provisioner (Ansible), testing tool used (Testinfra), the execution sequence scenario, etc.

Here is the code:

---
dependency:
  name: galaxy
driver:
  name: vagrant
  provider:
    name: virtualbox
platforms:
  - name: instance
    box: vagrantbox_name
    memory: 4096
    cpus: 2
    interfaces:
      # `network_name` is the required identifier, other keys map to arguments.
      - network_name: private_network
        ip: 192.168.50.20
        guest: 80
        host: 8080
    # List of raw Vagrant `config` options.
    provider_raw_config_args:
      - "customize [ 'modifyvm', :id, '--natdnshostresolver1', 'on' ]"
    # Dictionary of `config` options.
    config_options:
      ssh.keep_alive: yes
      ssh.remote_user: "'vagrant'"
provisioner:
  name: ansible
  inventory:
    host_vars:
      # Inventory used for Molecule when executing the Ansible role tested.     
      instance:
        variable1: value
        variable2: False
lint: |
  set -e
  yamllint .
  ansible-lint
scenario:
  test_sequence:
    - dependency
    - lint
    - cleanup
    - destroy
    - syntax
    - create
    - prepare
    - converge
    - idempotence
    - verify
    - cleanup
    - destroy
verifier:
  name: testinfra
  options:
    sudo: true
    v: 1
  • molecule/default/prepare.yml: Playbook for setting up the VM.
  • molecule/default/converge.yml: Playbook for executing the role in the VM.
  • molecule/tests/test_default.py: Testinfra tests cases. Used to test that everything works as expected after the role execution.
  • .yamlint: YAML file which defines the syntax rules of .yml files for linting purposes of the role.

Molecule execution

To execute Molecule commands we have to move to the molecule directory of the role:

cd roles/role_name/molecule/

We can execute the whole scenario execution sequence by executing the command:

molecule test

We also have the possibility of executing each step manually to control the behaviour of the execution sequence depending on our needs.

  • Creating the instance: create, dependency and prepare stages.
    molecule create
  • Execute the role: converge stage. Includes create, dependency and prepare stages in case they haven't been executed already.
    molecule converge
  • Execute the verify tests: verify stage.
    molecule verify
  • Destroy the instance: destroy stage.
    molecule destroy

Summary

In this tutorial we have learned the basic concepts of Molecule and we have installed the necessary tools and packages to execute Molecule using Vagrant and VirtualBox for the VMs provisioning and Testinfra for the verifying tests. In the next guides, we can find more detailed information about how to execute Molecule for testing different Ansible roles used to install a NetBackup Master Server in RHEL/CentOS/Azure and a CommVault Commserve in Windows Server 2016.

Using Molecule for testing an Ansible role to install a CommVault Commserve

Using Molecule to testing the deployment of a Veritas Netbackup Master Server with DR Process

Using Molecule to testing the deployment of a Veritas Netbackup Master Server with DR Process on Azure Cloud

comments powered by Disqus