- Use the official example of Molecule—do not use
Red Hat's example
as it’s outdated. - Refer to the Official Guide to Using Podman Containers with Molecule for up-to-date information.
- For basic setups, you don’t need extra configurations for Podman, as it’s the default behavior in Molecule.
- All you need is a
converge.yml
file and themolecule.yml
configuration file.
Plugins and installation
For now using the vagrant provider will result in error
There are plans to remvoe the support for the molecule plugins issue#510
To install plugins use this method ansible docs
Initialization
All you have to do is set up molecule.yml
, converge.yml
, and verify.yml
.
Commands
└── default
├── dependency # Installs role dependencies (e.g., via requirements.yml)
├── cleanup # Cleans up any leftover artifacts from previous runs
├── destroy # Removes any existing test instances
├── syntax # Checks the syntax of Ansible playbooks before running them
├── create # Creates the test environment (e.g., spins up Docker containers/VMs)
├── prepare # Applies additional setup (e.g., provisioning dependencies)
├── converge # Runs the actual Ansible playbook to configure the system
├── idempotence # Ensures rerunning `converge` produces no changes (idempotency check)
├── side_effect # Runs optional extra tasks that don't impact idempotence (e.g., notifications)
├── verify # Runs tests to validate the configuration (e.g., using Testinfra)
├── cleanup # Cleans up after testing
└── destroy # Destroys the test environment (again)
## More efficient one
scenario:
name: default
test_sequence:
- lint
- destroy
# - dependency
- syntax
- create
# - prepare
- converge
- idempotence
## - side_effect
- verify
- destroy
Note
- Navigate between
molecule converge
andmolecule verify
. molecule test
will execute the full cycle from startup to destroy (but is very verbose).- use
molecule test --destroy=never
to preserve the container
molecule converge
# Output:
# INFO Running default > prepare
# WARNING Skipping, prepare playbook not configured.
# INFO Running default > converge
# INFO Sanity checks: 'podman'
molecule verify
# Output:
# PLAY RECAP *********************************************************************
# instance : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
# INFO Verifier completed successfully.
Molecule.yml
The deployment configuration Chekcout the possible distros images
# Standard setup for using Podman in Molecule
role_name_check: 1
# to add additional collection to the base node img
dependency:
name: galaxy
options:
requirements-file: requirements.yml
ignore-errors: true
driver:
name: podman
# This is the seutp for the containers with systemd inside them
platforms:
- name: instance
image: "docker.io/geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2004}-ansible:${MOLECULE_TAG:-latest}"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
user: "rocky"
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
Converge.yml
The converge.yml
file contains the actual playbook tasks within your Molecule test.
- Sections
pre_tasks
: Prepare the container.tasks
: Main testing tasks.post_tasks
: Clean-up or post-test steps.
#Example Converge file that imports either playbooks or roles
- name: Converge
hosts: all
pre_tasks:
- name: Install dependencies
package:
name: curl
state: present
tasks:
- name: Create a test file
file:
path: /tmp/molecule_test.txt
state: touch
post_tasks:
- name: Remove test file
file:
path: /tmp/molecule_test.txt
state: absent
- import_playbook: ../../playbook.yml
Inventories
# U can easliy specyfie the host_vars and group_vars
# also /molecule/defualt/group_vars or host_vars will import it to
provisoner:
inventory:
group_vars:
all:
containers:
- name: adminer
image: docker.io/library/adminer:latest
ports:
- { host: "8080", container: "8080" }
Verify.yml
All it does it's run a playbook to verify the state of the playbook No special role just a playbook
# Example molecule verify playbook
- name: Verify
hosts: all
gather_facts: false
vars:
# If you want to import vars from the role, you have to either
# add it as an empty role (not recommended)
# or just use import_vars
tasks:
# Include vars from role
- name: Initialize role without actually running it
ansible.builtin.include_role:
name: my_role
tasks_from: init
# Or import them from role
- name: Include default vars
ansible.builtin.include_vars:
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/"
extensions:
- yml
- name: Check if {{ config }} exists
ansible.builtin.stat:
path: "{{ config }}"
register: file_stat
- name: Fail if file is missing
ansible.builtin.fail:
msg: "{{ config }}"
when: not file_stat.stat.exists
Delegete host
---
driver:
name: delegated # Avoids creating a local instance
platforms:
- name: backup_server
address: 192.168.1.200 # Replace with the actual remote machine IP/hostname
user: ansible # SSH user
ssh_port: 22 # SSH port
connection: ssh
instance_raw_config_args:
- "-o StrictHostKeyChecking=no"