Write an idempotent Ansible playbook
Task
Write a playbook that configures a service, and prove the property that distinguishes configuration management from a script: running it twice changes nothing the second time. Then break idempotence deliberately with the command module and see the difference.
Steps
- Write an inventory with one host (localhost is fine) grouped as
web. - Write a playbook that installs a web server, deploys a config from a template, and enables and starts the service -- using the
package,templateandservicemodules, each declaring desired STATE. - Run it and read the PLAY RECAP: note
changed=on the first run. - Run it again unchanged and confirm the recap shows
changed=0. This is idempotence, and it is what lets the playbook be re-run safely at any time. - Break it: replace the service task with a
command: systemctl restarttask. Run twice and observe it reportschangedevery time, because a bare command cannot know whether it changed anything. - Restore the module version. Use
--check --diffto preview what a run WOULD change without changing it, and confirm the preview is accurate. - Use a
when:condition on a gathered fact so one task runs only on the right OS family, and confirm it skips elsewhere.
Verify
ansible-playbook -i inventory site.yml | tee run1.txt
ansible-playbook -i inventory site.yml | tee run2.txt
grep -q 'changed=0' run2.txt && echo "idempotent: second run changed nothing"
ansible-playbook -i inventory site.yml --check --diff | grep -qi 'changed\|ok' && echo "check mode works"
changed=0 on the second run is the whole point. A playbook that reports changes every time it runs -- as the command version does -- has lost the property that makes --check meaningful and makes it safe to run from automation.
Notes
Prefer a module to command or shell for exactly this reason: a module declares state and reports truthfully whether it changed anything, while a bare command runs every time and always claims to have changed something. The --check preview is only trustworthy because the modules are honest about change.