Playbooks, Modules & Handlers
Inventory & a Basic Playbook
# inventory.ini
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com# site.yml
- hosts: webservers
become: true # escalate privileges (sudo) for this play
tasks:
- name: Install nginx
apt: # dedicated module — idempotent by design
name: nginx
state: present
- name: Deploy config
template:
src: nginx.conf.j2 # Jinja2 template
dest: /etc/nginx/nginx.conf
notify: restart nginx # only fires the handler if this task actually changed something
handlers:
- name: restart nginx
service:
name: nginx
state: restartedansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.yml --check # dry run — see what WOULD changeWhy Idempotency Matters
# BAD — shell/command are NOT idempotent by default; Ansible has no way
# to know if this actually changed anything, so it ALWAYS reports "changed",
# and any handler notified by it fires on every single run
- name: Install nginx (wrong way)
shell: apt-get install -y nginx
# GOOD — the apt module checks current state first, only reports
# "changed" when a real change happened
- name: Install nginx (correct)
apt:
name: nginx
state: presentKeep your own version of these notes — editable, searchable, and organised by your stack.
Start free