Part 12 — Roles¶
Chapter status: outline
This chapter is scoped but not yet written in full prose. The sections below define what each part will cover.
Roles are how Ansible content stops being "one big playbook" and becomes reusable, testable, shareable units. This chapter covers the standard structure and how to design roles that age well.
Why This Exists¶
- Without roles, teams end up with copy-pasted task blocks across playbooks — roles exist to make automation logic reusable across projects, hosts, and teams.
Problem Statement¶
- A flat playbook mixing "install nginx," "configure the firewall," and "deploy the app" in one file becomes unmaintainable past a handful of hosts or a handful of contributors.
Internal Architecture — The Standard Role Directory Layout¶
myrole/
tasks/main.yml # the role's task list
handlers/main.yml # handlers the role's tasks can notify
defaults/main.yml # lowest-precedence, freely overridable variables
vars/main.yml # higher-precedence, role-internal variables
files/ # static files served by copy/etc.
templates/ # Jinja2 templates served by template
meta/main.yml # role metadata, Galaxy info, dependencies
library/ # role-local custom modules (rare)
README.md
- How
roles:inclusion at the play level auto-wires this structure (tasks/main.ymlruns,handlers/main.ymlbecomes notifiable,defaults/varsload automatically) without explicitinclude_varscalls.
Workflow¶
- The load order when a play includes multiple roles: each role's
varsanddefaultsload in sequence, task execution proceeds role by role (or interleaved withpre_tasks/post_tasksas covered in Part 11).
Production Best Practices¶
- One role, one responsibility (a
nginxrole shouldn't also manage the database). - Always populating
defaults/main.ymlwith sensible values so a role works out of the box, withvars/main.ymlreserved for values that shouldn't typically change. - Writing a
meta/main.ymlwith accurategalaxy_infoanddependencieseven for internal-only roles, since it documents platform support and requirements. - Testing roles in isolation (previewed here, Molecule covered fully in Volume 5).
Common Mistakes¶
- Putting environment-specific values in
vars/main.ymlinstead ofdefaults/main.yml, making the role hard to reuse across projects. - Giant monolithic roles that try to do everything instead of composing several focused roles.
- Missing
meta/main.ymldependency declarations, causing roles to work only if included in a specific undocumented order.
Performance Considerations¶
- Deeply nested role dependencies (
meta/main.ymldependencies:) can cause unexpected duplicate execution if not guarded withrun_once/allow_duplicates: no.
Security Considerations¶
- Auditing third-party roles pulled from Galaxy before running them with
become: truein production — a role has the same access as any other task.
Interview Questions¶
- "What is the standard directory structure of an Ansible role?"
- "What's the difference between
defaults/main.ymlandvars/main.yml?" - "How do role dependencies in
meta/main.ymlwork?"
Hands-On Lab¶
- Use
ansible-galaxy role init myroleto scaffold a role, populatetasks/main.ymlanddefaults/main.ymlto install and configure a package, then include it from a playbook.
Summary¶
- Roles are Ansible's unit of reuse — the standard layout (
tasks,defaults,vars,handlers,meta) is a convention worth following exactly, because tooling (Galaxy, Molecule, linting) all assumes it.
Next¶
Continue to Part 13 — Collections.