Ansible Playbooks
Ansible’s superpower is imperative-looking playbooks with declarative-looking outcomes — as long as your modules are idempotent. Where that promise breaks is where the interesting bugs live.
Directory layout
Section titled “Directory layout”Directoryansible/
Directoryinventory/
- prod.yml
- staging.yml
Directorygroup_vars/
- all.yml
- webservers.yml
Directoryroles/
Directorycommon/
- tasks/main.yml
- handlers/main.yml
Directorytemplates/
- …
Directorynginx/
- …
Directorypostgres/
- …
Directoryplaybooks/
- site.yml
- patching.yml
- ansible.cfg
A well-behaved role task
Section titled “A well-behaved role task”- name: Install nginx ansible.builtin.package: name: nginx state: present notify: reload nginx
- name: Render main config ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: "0644" validate: "nginx -t -c %s" notify: reload nginx
- name: Ensure nginx enabled and started ansible.builtin.service: name: nginx state: started enabled: trueHandlers, notifications, and the run order
Section titled “Handlers, notifications, and the run order”Idempotence — the honest picture
Section titled “Idempotence — the honest picture”| Type of task | Idempotent? |
|---|---|
package, service, file | ✅ Built-in check-then-act |
template, copy | ✅ Content-diff before write |
command, shell | ❌ You must guard with creates: / changed_when: |
uri, get_url | Depends — check force, checksum |
- name: Bootstrap a one-shot script ansible.builtin.shell: /opt/init/bootstrap.sh args: creates: /var/lib/reetwiz/.bootstrappedDynamic inventory
Section titled “Dynamic inventory”plugin: azure.azcollection.azure_rminclude_vm_resource_groups: - core-rg - workloads-rgkeyed_groups: - prefix: tag key: tags['role']auth_source: cliplugin: amazon.aws.aws_ec2regions: - eu-west-1filters: tag:Environment: prodkeyed_groups: - prefix: role key: tags.RoleTesting playbooks locally
Section titled “Testing playbooks locally”# lintansible-lint playbooks/site.yml
# check mode + diff (dry run)ansible-playbook -i inventory/staging.yml playbooks/site.yml --check --diff
# molecule (per-role tests in ephemeral containers)cd roles/nginx && molecule test