C.W.K.
Stream
Lesson 04 of 08 · published

Ansible Playbooks — Idempotent Ops in YAML

~10 min · yaml, ansible, automation

Level 0Plaintext
0 XP0/64 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Server configuration as a list of tasks

Ansible playbooks are YAML lists of plays, each containing tasks that target hosts. The runtime sshes to each host and executes tasks in order, idempotently — re-running a playbook on an already-configured host is a no-op for unchanged tasks.

Five core sections

  • hosts: — which inventory group to target.
  • vars: — playbook-scoped variables (or include from vars/ files).
  • tasks: — ordered actions. Each is a module call (apt:, copy:, systemd:) with parameters.
  • handlers: — fire on notify: from a task. Run once at the end of the play, even if notified multiple times.
  • roles: — reusable bundles of tasks, vars, files, templates.

Inventory — the hosts file

Inventory can be YAML, INI, or dynamic (cloud API plugin). YAML inventory groups hosts and assigns variables.

Principle: Ansible's value is idempotency. Every well-written task is 'declare desired state,' not 'run this command.' Reach for the dedicated module (apt:, file:, systemd:) before falling back to shell: or command:. The dedicated module knows how to detect 'already done' and skip.

Code

A small playbook·yaml
---
- name: Configure web servers
  hosts: web
  become: true
  vars:
    nginx_user: www-data
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
        update_cache: true

    - name: Deploy nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        mode: '0644'
      notify: Restart nginx

    - name: Ensure nginx is running
      systemd:
        name: nginx
        state: started
        enabled: true

  handlers:
    - name: Restart nginx
      systemd:
        name: nginx
        state: restarted
YAML inventory·yaml
all:
  children:
    web:
      hosts:
        web1.example.com:
        web2.example.com:
      vars:
        nginx_workers: 4
    db:
      hosts:
        db1.example.com:
          ansible_user: postgres
Run the playbook·bash
# Dry run (--check)
ansible-playbook -i inventory.yaml site.yaml --check

# Apply
ansible-playbook -i inventory.yaml site.yaml

# Run only the web tasks
ansible-playbook -i inventory.yaml site.yaml --limit web

# Verbose for debugging
ansible-playbook -i inventory.yaml site.yaml -vvv

External links

Exercise

Pick one server-side change you've manually performed recently (install a package, deploy a config, set a systemd service). Express it as a 3-task Ansible play. Run with --check against a test host. Notice how the dry-run mode tells you exactly what would change — that report is the workflow win.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.