Writing your first playbook

Ansible · Essentials · 12 min

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 a name (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,
  • -v to -vvvv: more detail,
  • --syntax-check and --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.

Check yourself

  1. Task 2 fails on web1 but succeeds on web2. What happens to task 3 by default?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html