Ansible Fundamentals · Module 07 of 12

Your first playbook

Turn ad-hoc intentions into a repeatable playbook with named plays and tasks.

Learning objectives

By the end of this module, you should be able to:

  • Explain play, task and module relationships.
  • Write and run a small playbook.
  • Use syntax check, check mode and limited targeting before broad execution.

Playbooks are automation blueprints

A play maps a group of hosts to an ordered list of tasks. Each task invokes a module. A playbook can contain one or more plays and is executed with ansible-playbook.

Use descriptive names for plays and tasks. Clear names make output easier to audit and failures easier to locate.

Describe intent, not a transcript

A playbook should model the state you want: package present, configuration deployed, service enabled and started. Avoid converting every manual shell command into a command task when a dedicated module exists.

Use a cautious execution sequence

A practical workflow is syntax-check → list hosts → check mode where supported → one limited host → broader group. Check mode is a simulation and not every module can predict every effect, so it complements rather than replaces testing.

Worked examples

See the idea in practice.

Basic web playbook

- name: Configure web servers
  hosts: web
  become: true

  tasks:
    - name: Ensure nginx is installed
      ansible.builtin.package:
        name: nginx
        state: present

    - name: Ensure nginx is enabled and running
      ansible.builtin.service:
        name: nginx
        enabled: true
        state: started
  • hosts chooses the inventory group.
  • become requests privilege escalation for tasks in the play.
  • Tasks are executed in order.
  • FQCN module names make the content source explicit.

Safe pre-run sequence

ansible-playbook -i inventory.ini web.yml --syntax-check
ansible-playbook -i inventory.ini web.yml --list-hosts
ansible-playbook -i inventory.ini web.yml --check --limit web01
ansible-playbook -i inventory.ini web.yml --limit web01
  • Validate syntax first.
  • Confirm target resolution.
  • Simulate on one host where supported.
  • Then execute against the canary host.
Hands-on lab

Lab — Build and rerun your first playbook

Goal: Configure nginx on the web group and observe idempotence on a second run.

STEP 1

Create web.yml

- name: Configure web servers
  hosts: web
  become: true
  tasks:
    - name: Install nginx
      ansible.builtin.package:
        name: nginx
        state: present
    - name: Enable and start nginx
      ansible.builtin.service:
        name: nginx
        enabled: true
        state: started
STEP 2

Validate

ansible-playbook -i inventory.ini web.yml --syntax-check
ansible-playbook -i inventory.ini web.yml --list-hosts
STEP 3

Run it

ansible-playbook -i inventory.ini web.yml
STEP 4

Run it again

ansible-playbook -i inventory.ini web.yml

Verify

  • nginx is installed on each intended host.
  • The service is enabled and running.
  • The second run normally reports no changes if the desired state is already satisfied.

Expected outcome

  • A successful play recap with no unreachable or failed hosts.
  • The learner can explain why the second run should be quieter.

If it fails

  • If package installation fails, verify repository access and package naming on the managed OS.
  • If service management fails, verify the service unit name and init system.
Real-world connection

The second-run test is a simple but powerful way to expose automation that is not truly idempotent.

Avoid these traps

Common mistakes

  • Running a new playbook against the entire fleet before testing a limited host.
  • Using vague task names such as 'do config'.
  • Assuming --check is a perfect prediction of every module's behaviour.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1What is a play?

A mapping between a set of managed hosts and an ordered set of tasks.

2Why use --limit on a first production-style run?

To reduce blast radius by testing a controlled subset or canary host.

3What does a clean second run suggest?

That the desired state is already satisfied and the tasks are behaving idempotently.