Introduction
In the realm of DevOps and infrastructure as code (IaC), testing automation is a critical component to ensure the reliability and efficiency of configurations. Ansible, a powerful open-source automation tool, allows users to define and manage infrastructure as code through playbooks. Molecule, an extension of Ansible, facilitates the testing of Ansible roles in an isolated environment, providing a consistent and reproducible testing workflow.
One common scenario involves using Docker containers as test hosts within Molecule. Docker containers offer lightweight, portable environments that can be easily spun up and torn down, making them ideal for testing purposes. In this article, we will explore a Molecule setup utilizing Docker containers for the create, converge, and destroy steps.
Molecule Configuration
The Molecule configuration is defined in the molecule.yml file. This configuration specifies the test platforms and dependencies. In this example, the dependency is set to the Galaxy role, and the platforms include a Docker container based on the Ubuntu 22.04 image.
``yaml
dependency:
name: galaxy
options:
requirements-file: requirements.yml
platforms:
- name: molecule-ubuntu
image: ubuntu:22.04
`
The requirements.yml file lists the necessary Ansible collections, in this case, the community.docker collection.
`yaml
collections:
- community.docker
`
Create Playbook
The create.yml playbook is responsible for creating Docker containers based on the defined platforms. It uses the community.docker.docker_container Ansible module to start containers with a specified image and other parameters. If the containers are not running, the playbook fails, and detailed information is printed.
The playbook also dynamically adds the created containers to the Molecule inventory.
``yaml
- name: Create
hosts: localhost
gather_facts: false
vars:
molecule_inventory:
all:
hosts: {}
molecule: {}
tasks:
- name: Create a container
community.docker.docker_container:
name: "{{ item.name }}"
image: "{{ item.image }}"
state: started
command: sleep 1d
log_driver: json-file
register: result
loop: "{{ molecule_yml.platforms }}"
- name: Print some info
ansible.builtin.debug:
msg: "{{ result.results }}"
- name: Fail if container is not running
when: >
item.container.State.ExitCode != 0 or
not item.container.State.Running
ansible.builtin.include_tasks:
file: tasks/create-fail.yml
loop: "{{ result.results }}"
loop_control:
label: "{{ item.container.Name }}"
- name: Add container to molecule_inventory
vars:
inventory_partial_yaml: |
all:
children:
molecule:
hosts:
"{{ item.name }}":
ansible_connection: community.docker.docker
ansible.b