Stop 09 · Infrastructure as CodeTopics · 6/9

Ansible Playbooks & Roles

Part of the DevOps Roadmap

In short

Ad-hoc commands are fine for one-offs. Real server setup is twenty steps in order, reused across projects. Playbooks write those steps down, and roles package them so other playbooks can reuse them.

Playbooks define ordered sets of tasks to run against target hosts; Roles organize related playbooks, variables, and files into reusable, shareable units — Ansible's equivalent of Terraform modules.

The mascot hands colour-coded task folders to a cook, a flower decorator and a drummer.

Think of it like this

The wedding planner's folders

A wedding planner gives each team its own folder: the caterer's has the menu and timings, the decorator's has flowers and colours. The day's schedule just says which teams work when. Roles are those team folders; the playbook is the day's schedule.

Watch it happen

How a playbook uses roles

site.yml
role: common
role: nginx
tasks/
handlers/
templates/
defaults/

1/5site.yml is the playbook: which hosts, and which roles to apply to them, in order.

The big ideas

What you need to know

Plays run in order

A playbook is a list of plays. Each targets a host group and runs its tasks top to bottom.

Handlers react to change

Tasks can notify a handler. It only runs if something changed, which avoids needless restarts.

Roles have a fixed layout

tasks, handlers, templates, files, defaults. Run ansible-galaxy init roles/nginx to scaffold one.

Secrets with Vault

ansible-vault encrypts variable files, so passwords can live in the repo without being readable.

See it in code

Walk through the code

yaml
1- name: Set up web servers2  hosts: web3  become: true4  vars:5    app_port: 30006  tasks:7    - name: Install nginx8      ansible.builtin.apt: { name: nginx, state: present, update_cache: true }9    - name: Add site config10      ansible.builtin.template: { src: site.conf.j2, dest: /etc/nginx/conf.d/site.conf }11      notify: Reload nginx12  handlers:13    - name: Reload nginx14      ansible.builtin.service: { name: nginx, state: reloaded }

1/4One play targeting the web group, with sudo for every task.

Run it with ansible-playbook -i inventory.ini site.yml --check --diff first, then without --check. site.conf.j2 can use {{ app_port }}.

Save yourself the pain

Common mistakes

Oops

Restarting a service as a normal task at the end of every run.

Do this instead

Use a handler with notify, so the service only restarts when its config actually changed.

Oops

Putting every task for every server type into one long playbook.

Do this instead

Split into roles (common, nginx, app) and compose them. Smaller pieces are easier to test and reuse.

Your mission

Turn a playbook into a role

~40 min

Quick check

Why use a handler to reload nginx instead of a normal task at the end?

Go deeper

  1. 1Organize a set of related tasks from a playbook into a reusable Ansible Role.
  2. 2Practice using variables in a playbook to make it reusable across different environments.
  3. 3Explore Ansible Galaxy for community-maintained roles instead of writing everything from scratch.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge