📜 Playbook Anatomy

A playbook is just a YAML file — but every line has a job. Let's dissect one piece by piece.

1. The Structure: Playbook → Play → Task → Module

Everything nests like Russian dolls. A playbook contains one or more plays. Each play targets a group of hosts and contains tasks. Each task calls exactly one module.

📜 PLAYBOOK  (site.yml — the whole file) 🎬 PLAY 1 — "Configure web servers" (hosts: webservers) TASK: Install nginx module: apt TASK: Copy config module: template TASK: Start service module: service 🎬 PLAY 2 — "Configure databases" (hosts: databases) TASK: Install MySQL module: apt TASK: Create DB user module: mysql_user
🍕 Analogy: Playbook = cookbook, Play = one recipe ("pizza for the whole class"), Task = one step ("knead the dough"), Module = the kitchen tool that does that step (the oven, the mixer). You don't build an oven each time — you reuse it with different settings.

2. A Real Playbook, Fully Labeled

Every colored zone on the left is explained on the right — same colors:

--- - name: Configure web servers   hosts: webservers   become: true   vars:     http_port: 80   tasks:     - name: Install nginx       apt:         name: nginx         state: present     - name: Start nginx service       service:         name: nginx         state: started         enabled: true 🎬 PLAY HEADER • name — human label (shown in output) • hosts — which inventory group to hit • become: true — run with sudo • vars — variables for this play "WHO to configure + settings" 🔧 TASK 1 → module "apt" apt is the module (the tool). Its parameters say: package "nginx" must be present (installed). Already installed? → reports "ok". 🔧 TASK 2 → module "service" state: started → make sure it runs now enabled: true → auto-start on boot Again: describing the desired STATE, not typing commands.

3. YAML Rules — The 4 That Matter

RuleExampleWhy it matters
Indentation = structure (2 spaces, never tabs)tasks: then two spaces before - name:Wrong indent = wrong nesting = confusing errors
A dash - means "list item"- name: Install nginxPlays and tasks are LISTS — each starts with -
key: value pairsstate: presentEverything is key–value; note the space after :
--- starts the fileFirst line of the playbookMarks the start of a YAML document (convention)
⚠️ #1 student mistake: mixing tabs and spaces. YAML forbids tabs for indentation. Configure your editor to insert 2 spaces per Tab press.

4. Modules = Ansible's Toolbox

There are thousands of modules; you'll use these constantly:

ModuleWhat it doesMini example
apt / yum / dnfInstall/remove packagesapt: name=nginx state=present
copyCopy a file to the nodecopy: src=app.conf dest=/etc/app.conf
templateCopy a file with variables filled in (Jinja2)template: src=web.conf.j2 dest=/etc/web.conf
service / systemdStart/stop/enable servicesservice: name=nginx state=restarted
fileCreate dirs, set permissions, delete filesfile: path=/opt/app state=directory
userManage user accountsuser: name=deploy state=present
command / shellRun a raw command (last resort — not idempotent!)shell: /opt/app/migrate.sh
debugPrint a message/variable (great for learning)debug: msg="Port is {{ http_port }}"
Golden rule: always prefer a real module over shell/command. Modules are idempotent and report changed correctly; raw shell commands run blindly every time.

5. Reading the Output

When you run ansible-playbook site.yml, each task prints one of three results per host:

ok ✅ Already in desired state. Nothing was changed. changed 🔧 Ansible DID something (installed, copied, restarted…) failed ❌ Task errored — host is removed from the rest of the play.
🔓 You're reading a free chapter of Ansible — the first two are open.
Unlock the rest of this course with a one-time payment.
Unlock this course →
🔓 See course prices