Ansible Molecule Testing Prompt
Test Ansible roles with Molecule — scenarios, drivers (Docker/Podman/Vagrant), verifiers (Ansible/Testinfra), idempotence.
- Target user
- Ansible engineers writing role tests
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior Ansible engineer who has set up Molecule tests for many roles — fast feedback, idempotence checks, CI integration. I will provide: - The role being tested - Current molecule.yml (if any) - Symptom (test fails, slow, can't run locally) Your job: 1. **Molecule basics**: - Test framework for Ansible roles - Scenarios in `molecule/<scenario>/` - Driver creates test infrastructure (Docker, Podman, Vagrant) - Playbook runs role (`converge.yml`) - Verifier checks results 2. **For driver choice**: - **Docker / Podman** — fast, container-based; best for most - **Vagrant** — VM-based; for kernel-level tests - **Delegated** — bring-your-own; for cloud tests 3. **For scenarios**: - Default scenario in `molecule/default/` - Multiple scenarios for variations (e.g., per OS) 4. **For test phases**: - `dependency` — pull dependencies - `create` — spin up test instances - `prepare` — pre-setup - `converge` — run role - `idempotence` — run again, expect no change - `verify` — assertions - `destroy` — cleanup 5. **For verifier**: - **Ansible** — assertions in playbook - **Testinfra** — Python tests (now Pytest-based) 6. **For CI integration**: - GitLab CI / GitHub Actions - Molecule + Docker-in-Docker or similar 7. **For Multi-OS testing**: - `platforms` list in molecule.yml - Run role on Ubuntu, RHEL, etc. 8. **For debugging**: - `molecule converge` — run without destroy - `molecule login` — shell into instance - `molecule destroy` to clean up Mark DESTRUCTIVE: tests against production-like instances (state pollution), running molecule with sudo creds (host compromise), incomplete cleanup leaving resources. --- Role: [DESCRIBE] Current molecule.yml: [PASTE] Symptom: [DESCRIBE]
Why this prompt works
Tests validate role behavior. This prompt walks setup.
How to use it
- Default scenario with Docker.
- Add OS variations.
- Idempotence test.
- CI integration.
Useful commands
# Install
pip install molecule molecule-docker ansible-lint
# Initialize molecule in a role
cd roles/myrole
molecule init scenario --driver-name docker
# Run all phases
molecule test # create + converge + verify + destroy
# Run subset
molecule create # just spin up
molecule converge # apply role
molecule idempotence # run again
molecule verify # check
molecule destroy
# Debug
molecule login # shell into instance
molecule converge -- --verbose
# Test specific scenario
molecule test -s my-scenario
Patterns
molecule.yml (Docker driver, multi-OS)
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: ubuntu-22
image: docker.io/geerlingguy/docker-ubuntu2204-ansible:latest
pre_build_image: true
privileged: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
command: "/lib/systemd/systemd"
- name: rocky-9
image: docker.io/geerlingguy/docker-rockylinux9-ansible:latest
pre_build_image: true
privileged: true
command: "/sbin/init"
provisioner:
name: ansible
config_options:
defaults:
callbacks_enabled: profile_tasks, timer
verifier:
name: ansible
converge.yml
---
- name: Converge
hosts: all
become: true
vars:
web_port: 8080
web_workers: 4
roles:
- role: myrole
verify.yml (Ansible verifier)
---
- name: Verify
hosts: all
become: true
tasks:
- name: Check service running
service:
name: nginx
state: started
check_mode: true
register: svc_check
- name: Assert service is running
assert:
that:
- svc_check is not changed
fail_msg: "nginx is not running"
- name: Check port listening
wait_for:
port: 8080
timeout: 5
- name: Get config content
slurp:
src: /etc/nginx/nginx.conf
register: config
- name: Assert workers setting
assert:
that:
- "'worker_processes 4' in (config.content | b64decode)"
Testinfra verifier (Python)
# molecule/default/tests/test_default.py
import pytest
def test_nginx_running(host):
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
def test_nginx_port(host):
socket = host.socket("tcp://0.0.0.0:8080")
assert socket.is_listening
def test_config_file(host):
config = host.file("/etc/nginx/nginx.conf")
assert config.exists
assert config.user == "root"
assert "worker_processes 4" in config.content_string
# molecule.yml
verifier:
name: testinfra
CI integration (GitLab)
molecule:
image: quay.io/ansible/molecule:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
before_script:
- pip install molecule molecule-docker ansible-lint
script:
- cd roles/myrole
- molecule test
Common findings this catches
- Test setup slow → use pre-built images.
- Idempotence fails → fix changed_when in role.
- Privileged container needed for systemd → set privileged: true.
- Test passes but real fails → OS image too different.
- CI Docker-in-Docker issues → check driver config.
- Tests stuck → molecule destroy —force.
- Cleanup leaves resources → manual docker prune.
When to escalate
- Test infrastructure scaling — engineering.
- Cross-OS test design — strategic.
- Performance testing — separate framework.
Related prompts
-
Ansible CI/CD Lint & Test Pipeline Prompt
Build Ansible CI/CD pipelines — lint, syntax check, Molecule tests, vault validation, deploy stages.
-
Ansible Idempotency Design Prompt
Make Ansible tasks idempotent — when to use changed_when / failed_when, check mode, validating shell tasks.
-
Ansible Roles Structure Best Practices Prompt
Design Ansible roles — defaults vs vars, meta dependencies, role parameters, tags, idempotency.