Using AI to Write Ansible Molecule Tests for Your Roles
Most Ansible roles ship untested. Here's how I use AI to scaffold Molecule scenarios and write Testinfra assertions that actually catch regressions.
- #iac
- #ansible
- #ai
- #molecule
- #testing
Ask a room of Ansible users how many of their roles have automated tests, and watch the hands stay down. I get it — writing Molecule scenarios and Testinfra assertions feels like more work than the role itself, and there’s always something more urgent. But untested roles are how a “small change” to a shared role breaks fourteen playbooks at once. This is the kind of high-value, low-glamour work where AI genuinely changes the economics, because it can scaffold the boilerplate in seconds.
The usual rule holds: AI is a fast junior engineer that writes the test scaffolding, but I review every assertion to make sure it tests real behavior, and I run everything in an ephemeral container — never against a real host.
Why Molecule, and why tests at all
Molecule spins up a throwaway instance (usually a Docker container or Podman), applies your role, and lets you assert that the host ended up in the state you intended. It’s the closest thing Ansible has to a unit test. Without it, your only test is “deploy to prod and see what happens,” which is not a test, it’s a bet.
The two pieces AI helps with are the scenario (how Molecule provisions and converges) and the verification (what you assert afterward).
Scaffold the scenario with AI, then read it carefully
I start from molecule init scenario and then hand the role to AI:
“Here’s my Ansible role. Generate a Molecule
molecule.ymlusing the Docker driver, targeting a base image that matches our production OS. Add aconverge.ymlthat applies the role with realistic variables. Use placeholder values for any secret.”
A typical generated molecule.yml:
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: "geerlingguy/docker-ubuntu2204-ansible:latest"
pre_build_image: true
provisioner:
name: ansible
verifier:
name: testinfra
That’s correct boilerplate, but I check the image matches our real OS family — AI will happily pick a generic Ubuntu image when production is RHEL, and a role that passes on the wrong base is worse than no test.
The verification is where the value lives
Anyone can write a test that asserts “the play ran.” The useful test asserts the outcome — the service is enabled and listening, the config file has the right content, the user exists with the right shell. AI writes solid Testinfra assertions because the patterns are well-known:
# molecule/default/tests/test_default.py
import os
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ["MOLECULE_INVENTORY_FILE"]
).get_hosts("all")
def test_nginx_running_and_enabled(host):
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
def test_nginx_listening_on_443(host):
assert host.socket("tcp://0.0.0.0:443").is_listening
def test_config_file_rendered(host):
config = host.file("/etc/nginx/conf.d/app.conf")
assert config.exists
assert config.user == "root"
assert config.contains("server_name app.example.com")
These assert real end state, not just “no errors.” When AI proposes them, I review each one against what the role is actually supposed to guarantee. I’ll often add assertions it missed — for example, that a port is not listening, which catches accidental exposure.
Pro Tip: Ask AI to write at least one “negative” assertion per role — something that should NOT be true, like a port that should be closed or a file that should be absent. Positive-only test suites pass even when the role does too much.
Test idempotency as a first-class assertion
Molecule has idempotency checking built in, and it’s the most valuable test in the suite. The default sequence runs converge then re-runs it and fails if anything reports changed:
molecule test
If your role isn’t idempotent, this catches it before prod does. I make sure the generated molecule.yml doesn’t disable the idempotence step, because AI sometimes trims it to make the scenario “simpler.” I want it loud and mandatory.
Run it all in ephemeral containers
This is the safety property that makes AI-generated tests low-risk: Molecule runs against disposable containers that get destroyed after each run. Nothing touches a real host, no real inventory, no production data. Even if AI generated a test that did something destructive, the blast radius is a container that’s about to be deleted anyway.
molecule create # spin up the throwaway instance
molecule converge # apply the role
molecule verify # run the assertions
molecule destroy # tear it all down
I still read what converge.yml does before running it, but the ephemeral environment is a real safety net that I don’t have when running playbooks against live infrastructure.
Keep secrets out of the test fixtures
Test variables use obviously-fake placeholders. A role that needs a database password gets db_password: "test-only-not-a-real-secret" in the converge vars. I never put real vault content in a Molecule scenario, partly because tests shouldn’t depend on secrets and partly because test fixtures end up committed to the repo where everyone can see them. If a role’s behavior genuinely depends on a secret’s shape, I use a fake of the same shape.
Wire it into CI
Tests that only run locally rot. I run molecule test in CI on every PR that touches a role, so a broken role never merges. The IaC testing strategies guide covers the CI wiring in more depth, and I keep my test-generation prompts in the prompt workspace so the scaffolding stays consistent across roles.
The honest truth is that AI didn’t make me a better tester — it just removed the excuse. The boilerplate that used to take an afternoon takes minutes, which means I actually write the tests now. The judgment about what to assert stays with me, and the containers keep it all safe. For the rest of the series see the IaC category, and GitHub Copilot is handy for the inline test-writing flow if you live in an editor.
Stop shipping untested roles. Let AI write the scaffolding, you write the assertions, and let Molecule’s containers absorb the risk.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.