Stage 4 · Provision
Roles & Collections
Anatomy of a Role
tasks, handlers, defaults, templates, and the directory layout.
What Is a Role?
A role packages all the tasks, handlers, variables, templates, and files needed to configure a component into a reusable unit. Instead of writing one monolithic playbook, you compose smaller roles — nginx, postgresql, monitoring — and assemble them into playbooks.
Directory Structure
roles/
nginx/
tasks/
main.yml # Primary task file
install.yml # Additional task files
configure.yml
handlers/
main.yml # Handler definitions
defaults/
main.yml # Default variables (lowest precedence)
vars/
main.yml # Role variables (higher precedence)
templates/
nginx.conf.j2 # Jinja2 templates
files/
custom.conf # Static files to copy
meta/
main.yml # Role metadata and dependencies
README.md # Role documentation
molecule/ # Testing scenariosNot all directories are required. A minimal role needs only tasks/main.yml. Add directories as needed for your role's functionality.
Key Files
---
- name: Include installation tasks
import_tasks: install.yml
tags: [install]
- name: Include configuration tasks
import_tasks: configure.yml
tags: [configure]
- name: Include service tasks
import_tasks: service.yml
tags: [service]Split tasks into logical files and import them from main.yml. This keeps each file focused and maintainable.
---
- name: Restart nginx
service:
name: nginx
state: restarted
- name: Reload nginx
service:
name: nginx
state: reloadedHandlers defined in a role are available to tasks within that role. They trigger when notified from role tasks.
Using Roles in Playbooks
---
- name: Configure web servers
hosts: webservers
become: yes
roles:
- common
- nginx
- role: app
vars:
app_port: 8080
- monitoring
- role: backup
when: environment == "production"roles is a shorthand that includes role tasks. Use the role: key when you need to pass variables or conditions.
The roles section in a playbook is syntactic sugar for include_role. Both work, but roles is cleaner for simple inclusion. Use include_role or import_role when you need dynamic role inclusion.
Role Lifecycle
- Design — define the role's purpose and variable interface
- Implement — write tasks, handlers, templates, and defaults
- Test — use Molecule to test the role in isolation
- Publish — upload to Ansible Galaxy or a private collection
- Version — tag releases and maintain a changelog
- Maintain — update for new OS versions and Ansible releases
A well-designed role does one thing well. Compose multiple roles to build complex configurations. This follows the Unix philosophy and makes automation maintainable.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.