Chapter Eight

Roles & Reuse

The flat Larkspur web playbook has outgrown itself — a dozen tasks, three handlers, four templates. This chapter packages it into the reusable larkspur_web role: the standard directory layout, defaults as a public interface, dependencies and composition, the static and dynamic ways to apply it, and how Galaxy and collections distribute the result. By the end the scattered tasks are one named, idempotent, publishable unit.

7 topics

A role is the unit Ansible gives you for reuse: a packaged bundle of tasks, handlers, templates, files, and defaults in a fixed directory layout the engine knows how to load by convention. It is the Ansible analog of a Terraform module — a named, versioned thing you drop into any playbook instead of copying a wall of YAML between projects. The whole chapter is the same worked refactor: the Layer A web stack, scattered across a flat playbook, becomes larkspur_web.

The order matters. First the anatomy and the auto-load convention that makes a role "just work," then where variables live and why defaults/ versus vars/ is a precedence decision, then dependencies and the static-versus-dynamic application split that mirrors import versus include. The last three pages move outward — Galaxy for community roles, collections and FQCN for the modern packaging model, and the discipline that separates a role that runs from a role worth reusing.

Topics in This Chapter

Topic 45
Role Anatomy
The standard subdirectories, the main.yml auto-load convention, and why templates resolve relatively inside a role. Splitting a large tasks/main.yml into an imported index, and what a role is concretely — a unit addressed by name, not by path.
RolesStructure
Topic 46
Role Variables
defaults/main.yml is the role's public interface at the bottom of precedence; vars/main.yml is high-precedence internal constants. Where each lands in the 22 levels, why role variables must be namespaced, and the interface contract that makes a role safe to reuse.
RolesVariables
Topic 47
Role Dependencies and meta
What meta/main.yml carries — galaxy_info and dependencies — and how a declared dependency runs before the dependent role. Why dependency chains hide execution order, and when explicit composition in the playbook beats a buried meta dependency.
Rolesmeta
Topic 48
include_role and import_role
Three ways to apply a role and the parse-time-versus-runtime split between them. The roles: keyword, static import_role, dynamic include_role, passing per-invocation vars:, and why only include_role can loop.
RolesApplication
Topic 49
Ansible Galaxy
The public registry of community roles, ansible-galaxy role install, and requirements.yml as a lockfile for role dependencies. Vetting a community role before it lands in your deploy path, and why you pin a version instead of floating HEAD.
RolesGalaxy
Topic 50
Collections and FQCN
The modern packaging unit — modules, roles, and plugins under a namespace.collection name. Why ansible.builtin.copy is now how you address a module, which collection ansible-core ships, and how requirements.yml declares both roles and collections.
CollectionsFQCN
Topic 51
Designing Reusable Roles
The gap between a role that runs and a role worth reusing is interface design. Defaults as API, single-purpose roles, idempotency as a hard requirement in a rolling deploy, and argument_specs that fail fast — the assembled larkspur_web role.
RolesDesign