AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Molecule: Test Roles & Collections in Containers (Guide)

By Luca Berton · Published 2024-01-01 · Category: installation

Complete guide to testing Ansible roles with Molecule. Set up Docker-based testing, write verify playbooks, configure scenarios, and integrate with CI/CD.

Ansible Molecule: Test Roles & Collections in Containers (Guide)

Introduction

When developing Ansible roles within a collection, it is crucial to ensure that your code functions as expected and integrates seamlessly with the broader infrastructure. Molecule, a testing framework for Ansible roles, allows developers to automate the testing process, making it easier to catch issues early in the development cycle. In this article, we will explore how to test an Ansible role within a collection using Molecule, with a focus on the converge action.

See also: Ansible Molecule Docker: Test Roles in Containers (Guide)

Molecule in Ansible Collection

Adding Molecule to your Ansible collection is a straightforward process that enhances your development and testing workflow. Start by creating a new directory within your collection named "extensions." Navigate to this newly created directory using the command line and then initialize a new default Molecule scenario with the following:

cd <path to your collection>/extensions/
molecule init scenario

This step sets the foundation for incorporating Molecule into your collection, allowing you to seamlessly integrate testing and development practices. The newly created scenario within the "extensions" directory becomes a pivotal component in orchestrating Molecule's testing lifecycle for your Ansible roles and playbooks.

Example Role Structure

To illustrate the testing process, consider the structure of a sample role located at myrole/tasks/main.yml:

---
- name: Task running inside the role
  ansible.builtin.debug:
    msg: "This is a task from my_role"

This simple task, when executed, prints a debug message to provide a basic Playbooknstration of the role's functionality.

See also: Ansible Troubleshooting: Fix ModuleNotFoundError 'ansible'

Configuring Molecule with molecule.yml

The configuration file molecule.yml outlines the testing environment and Ansible provisioner settings. Below is an example configuration:

---
platforms:
  - name: instance

provisioner: name: ansible config_options: defaults: collections_path: ${ANSIBLE_COLLECTIONS_PATH}

In this configuration, we define a single platform named instance and configure the Ansible provisioner. The collections_path option ensures that Ansible can locate the necessary collections during testing.

Customizing the Converge Action in converge.yml

The converge.yml file controls the steps executed during the Molecule converge action. Customize this file based on your role's requirements. Below is an example that includes a role from the collection:

---
- name: Include role from the collection
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Testing role
      ansible.builtin.include_role:
        name: foo.bar.my_role
        tasks_from: main.yml

This snippet Playbooknstrates how to include the my_role role from the foo.bar collection and execute the tasks defined in its main.yml file. Adjust the role and collection names to match your specific project.

By combining these elements, you create a cohesive testing environment for your Ansible roles within a collection. This structured approach facilitates the development, testing, and refinement of roles, ensuring their reliability and effectiveness in diverse environments.

See also: Ansible Automation: Complete Guide to IT Automation with Playbook Examples

The converge.yml File

Upon initialization of a new Ansible collection, Molecule generates a default file named converge.yml. This file serves as a playbook designed to execute the entire role, covering all necessary steps from start to finish. While the converge.yml file can be modified according to specific requirements, it serves as an excellent starting point for those unfamiliar with Molecule.

To initiate the testing process, developers can use the following command:

molecule converge

This command triggers Molecule to execute the role within an isolated test environment. The process involves performing the necessary steps outlined in the role and halting execution after the converge action. This provides developers with an opportunity to inspect the environment and make any required adjustments.

To execute the test, navigate to the extensions directory within your collection:

cd <path to your collection>/extensions/

Run the following command to trigger the converge action:

molecule converge

This command executes the steps defined in the role but stops after the converge action, enabling developers to inspect the environment and make necessary adjustments during the development process.

Links

• https://ansible.readthedocs.io/projects/molecule/

Conclusion

In conclusion, leveraging Molecule for testing Ansible roles within collections streamlines the development and debugging process. The converge.yml file, generated by Molecule, serves as a convenient starting point for testing the entire role. Additionally, the ability to use Molecule for live development ensures that developers can iteratively test and refine their roles until they meet the desired standards. By incorporating these testing practices into your Ansible collection development workflow, you can build robust and reliable roles with confidence.

Install Molecule

pip install molecule molecule-docker
# Or with podman
pip install molecule molecule-podman

Initialize Role with Molecule

# New role with Molecule
molecule init role my_role

# Add Molecule to existing role cd roles/my_role molecule init scenario

Project Structure

roles/my_role/
├── defaults/main.yml
├── tasks/main.yml
├── handlers/main.yml
├── molecule/
│   └── default/
│       ├── molecule.yml        # Configuration
│       ├── converge.yml        # Run the role
│       ├── verify.yml          # Test assertions
│       ├── prepare.yml         # Pre-setup (optional)
│       └── destroy.yml         # Cleanup (optional)
├── meta/main.yml
└── tests/

molecule.yml

---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: ubuntu
    image: ubuntu:24.04
    pre_build_image: true
    command: /bin/bash
    tmpfs:
      - /run
      - /tmp
  - name: rocky
    image: rockylinux:9
    pre_build_image: true
    command: /bin/bash
provisioner:
  name: ansible
  inventory:
    host_vars:
      ubuntu:
        ansible_python_interpreter: /usr/bin/python3
verifier:
  name: ansible

converge.yml

---
- name: Converge
  hosts: all
  become: true
  vars:
    myapp_port: 8080
    myapp_env: test
  roles:
    - role: my_role

verify.yml

---
- name: Verify
  hosts: all
  become: true
  tasks:
    - name: Check package installed
      package_facts:

- assert: that: "'nginx' in ansible_facts.packages" fail_msg: "nginx not installed!"

- name: Check service running command: systemctl is-active nginx changed_when: false

- name: Check port listening wait_for: port: 80 timeout: 5

- name: Check config file stat: { path: /etc/nginx/nginx.conf } register: config - assert: that: config.stat.exists

Run Tests

# Full test cycle
molecule test

# Step by step molecule create # Create containers molecule converge # Run the role molecule verify # Run tests molecule idempotence # Test idempotency molecule destroy # Clean up

# Keep containers for debugging molecule converge molecule login -h ubuntu # SSH into container

Test Idempotency

molecule idempotence
# Runs converge twice — second run should have 0 changes

Multiple Scenarios

molecule/
├── default/          # Docker-based
│   └── molecule.yml
├── vagrant/          # Vagrant VMs
│   └── molecule.yml
└── ec2/              # AWS instances
    └── molecule.yml
molecule test -s vagrant

CI/CD Integration

# GitHub Actions
- name: Run Molecule tests
  run: |
    pip install molecule molecule-docker ansible-core
    molecule test
  env:
    PY_COLORS: '1'
    ANSIBLE_FORCE_COLOR: '1'

FAQ

Molecule vs ansible-test?

Molecule tests roles in real containers/VMs. ansible-test is for testing collections (unit tests, sanity checks, integration tests). Use Molecule for roles, ansible-test for collections.

Can I test without Docker?

Yes — use delegated driver for localhost, vagrant for VMs, or cloud drivers for AWS/GCP instances.

How do I debug failing tests?

molecule converge   # Don't destroy
molecule login      # Shell into container
# Debug manually, then:
molecule destroy

Related Articles

the Ansible Galaxy referenceAnsible become methods comparedstructuring playbooks with Ansible roles

Category: installation

Watch the video: Ansible Molecule: Test Roles & Collections in Containers (Guide) — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home