Check mode, linting and Molecule

Ansible · Advanced · 10 min

Untested automation fails at the worst moment, usually against production.

Check mode (--check) asks every module to report what it would change without changing it; --diff shows file and template differences. Together they're the closest thing to terraform plan. Limits: commands and shell tasks are skipped in check mode (no way to know), and tasks depending on earlier changes may fail. Per task, check_mode: false forces a read-only command to run even in check mode, and check_mode: true makes a task always simulate.

ansible-lint catches problems statically: missing task names, non-FQCN module names, command used where a module exists, missing changed_when, risky file permissions, deprecated syntax. Profiles from min to production set strictness; run it in pre-commit and CI. yamllint complements it for formatting.

Molecule tests roles end to end: it creates instances (usually containers via Podman or Docker, or VMs), applies the role (converge), runs it again to verify idempotence (a second run with any change fails the test), then runs verification (Ansible asserts, or Testinfra) and destroys everything. molecule test runs the whole sequence; molecule converge and login help while developing.

A good CI pipeline: yamllint, ansible-lint, --syntax-check, Molecule per role on the OS versions you support, and a --check --diff run against staging before production.

Example

ansible-playbook -i inventory/prod site.yml --check --diff --limit web1
# TASK [nginx : Configure nginx]
# --- before: /etc/nginx/nginx.conf
# +++ after: /etc/nginx/nginx.conf
# -worker_processes 2;
# +worker_processes 4;
# changed: [web1]

ansible-lint --profile production roles/nginx
# name[missing]: All tasks should be named. roles/nginx/tasks/main.yml:12
# fqcn[action-core]: Use FQCN for builtin module actions (service).

cd roles/nginx && molecule test
# ... converge, idempotence: "Idempotence completed successfully.", verify, destroy

Remember

  • --check --diff previews changes; commands are skipped in check mode
  • ansible-lint enforces best practices in CI
  • Molecule converges, checks idempotence, verifies and destroys

Watch out for

  • Trusting check mode for playbooks full of shell tasks, which it simply skips.

Check yourself

  1. What does Molecule's idempotence step check?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ansible.com/ansible/latest/playbook_guide/playbooks_checkmode.html