Playbooks are Ansible's real unit of work: versioned, repeatable automation.
A playbook is a YAML list of plays. Each play maps a group of hosts to a list of tasks:
hosts: the pattern to target.become: true: escalate privileges (sudo) for the play.vars: variables for the play.tasks: an ordered list; each has aname(shown in output; always write one) and one module call.
Execution model: tasks run in order, and each task runs on all targeted hosts (in parallel, up to forks, default 5) before the next task starts. If a task fails on a host, that host is dropped from the rest of the play while others continue.
Run with ansible-playbook -i inventory.yml site.yml. Useful flags:
--check --diff: preview changes,--limit web1: restrict hosts,--start-at-task "Install nginx"and--step: control flow while debugging,-vto-vvvv: more detail,--syntax-checkand--list-tasks: validate without running.
The PLAY RECAP at the end lists per-host counts: ok, changed, unreachable, failed, skipped, rescued, ignored. Aim for a second run that shows changed=0.
Tasks call modules with YAML mappings as arguments (name: nginx), not the key=value strings used in ad-hoc commands.
Example
# site.yml
- name: Configure web servers
hosts: web
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Deploy the home page
ansible.builtin.copy:
content: "<h1>Hello from {{ inventory_hostname }}</h1>\n"
dest: /var/www/html/index.html
mode: "0644"
- name: Ensure nginx is running and enabled
ansible.builtin.service: {name: nginx, state: started, enabled: true}
# ansible-playbook -i inventory.yml site.yml
# PLAY RECAP: web1 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 ...Remember
- A playbook is a list of plays: hosts + tasks
- Each task finishes on all hosts before the next starts
- PLAY RECAP: aim for changed=0 on the second run
Watch out for
- Unnamed tasks, which make output and debugging much harder.