Ansible roles.
A role bundles tasks, handlers, templates, files, and variables into one reusable directory layout β and Ansible auto-loads each subdir's main.yml. Watch the tree light up subdir by subdir, then pull a community role off Galaxy with a requirements.yml lockfile.
Ansible roles animated tutorial. The standard role directory layout β tasks, handlers, templates, files, vars, defaults, and meta main.yml files that Ansible auto-loads. Using roles in a play with parameters, import_role versus include_role, defaults versus vars variable precedence, installing community roles and collections from Ansible Galaxy, pinning them in requirements.yml, role dependencies in meta/main.yml, and Fully-Qualified Collection Names (FQCN). RHCE EX294 ready.A role is just a fixed directory layout Ansible knows how to auto-load. Watch a role's tree light up subdir by subdir β tasks, handlers, templates, defaults vs vars β then pull one off Galaxy with requirements.yml.
- Β·Comfortable writing Ansible playbooks and tasks
- Β·Know what handlers and templates (.j2) are
- Β·Basic ansible.cfg / inventory familiarity
Scaffold a role with the standard layout, use it in a play with parameters, place variables correctly in defaults vs vars, and install community roles and collections from Galaxy via requirements.yml.
pace: 11 minutes
ββ tasks/main.ymlauto-loadedββ handlers/main.ymlauto-loadedββ templates/ββ files/ββ vars/main.ymlauto-loadedββ defaults/main.ymlauto-loadedββ meta/main.ymlauto-loaded- hosts: webservers
roles:
- webserverWhy roles β stop copy-pasting
A role is a self-contained, reusable bundle of tasks, handlers, templates, files, and variables that follows a STANDARD directory layout. Drop a role into a project and Ansible auto-loads main.yml from each subdir β there are no include paths to wire up by hand. Roles keep your playbooks short: a 200-line web setup collapses to one line, `roles: [webserver]`. And because the layout is a fixed convention, a role you write and a role pulled off Ansible Galaxy plug in exactly the same way.
$ansible-galaxy init webserver$ls roles/webserver/$roles:\n - webserverA role is just a convention β a fixed directory layout where Ansible auto-loads tasks, handlers, templates, and defaults from each subdir's main.yml. Learn the layout once and every role β yours or one pulled off Galaxy β drops into a play with a single line: roles: [webserver].
$ansible-galaxy init NAME$roles/NAME/tasks/main.yml$handlers/main.yml$templates/ (by basename)$files/ (copy src)$vars/main.yml$defaults/main.yml$meta/main.yml$roles:\n - role: NAME\n k: v$- import_role: name=NAME$- include_role: name=NAME$ansible-galaxy role install X$ansible-galaxy install -r requirements.yml$ansible-galaxy collection install ns.coll$ns.coll.module (FQCN)Which role subdir is auto-loaded as the role's main task list?
You want a role variable users can easily override from inventory. Put it in defaults/ or vars/?
What does `ansible-galaxy init webserver` do?
import_role vs include_role β what's the difference?
These aren't graded β they're just for active recall, which is what actually makes the lesson stick.
Ansible Vault
Roles and group_vars often hold passwords and keys. Learn to encrypt sensitive data right in your repo with Ansible Vault β so secrets ship safely beside your playbooks.
Read this lesson as text6 chapters Β· quiz answers
01Why roles β stop copy-pasting
A role is a self-contained, reusable bundle of tasks, handlers, templates, files, and variables that follows a STANDARD directory layout. Drop a role into a project and Ansible auto-loads main.yml from each subdir β there are no include paths to wire up by hand. Roles keep your playbooks short: a 200-line web setup collapses to one line,
roles: [webserver]. And because the layout is a fixed convention, a role you write and a role pulled off Ansible Galaxy plug in exactly the same way.$ ansible-galaxy init webserverβ scaffold the standard skeleton$ ls roles/webserver/β see the standard subdirs$ roles:\n - webserverβ use it β one line in a play
02The directory layout
Every role is the same set of subdirs, each with a main.yml that Ansible loads automatically. tasks/ holds the work, handlers/ holds handlers you notify, templates/ holds .j2 files (referenced by basename), files/ holds static files for copy, vars/ holds high-precedence vars, defaults/ holds the lowest-precedence (overridable) vars, and meta/ holds metadata and role dependencies. You never write include paths β being in the right subdir IS the wiring. A template at templates/httpd.conf.j2 is reached as just
httpd.conf.j2; a static file under files/ is thesrc=for the copy module.$ roles/webserver/tasks/main.ymlβ the work runs from here$ template: src=httpd.conf.j2β templates/ ref by basename$ copy: src=index.htmlβ files/ is the copy source dir
03Using roles in a play
The simplest way is a static
roles:list on the play β those roles run after pre_tasks and before the play's own tasks. Pass parameters by giving the role as a mapping with extra keys (they become role vars). For finer control, call a role from inside tasks:import_roleis STATIC (parsed at parse time, so tags and when apply to all its tasks), whileinclude_roleis DYNAMIC (evaluated at runtime, so it can be looped or made conditional). Reach for the dynamic include only when you actually need run-time behaviour.$ roles:\n - role: webserver\n http_port: 8080β run with a parameter$ - import_role:\n name: webserverβ static β parsed at parse time$ - include_role:\n name: webserverβ dynamic β runtime, loopable
04defaults vs vars β precedence
These two subdirs look alike but sit at opposite ends of variable precedence. defaults/main.yml is the LOWEST precedence in all of Ansible β it exists to be overridden by inventory vars, group_vars, play vars, or -e extra-vars. vars/main.yml is HIGH precedence and is genuinely hard to override. The rule: put tunables a user might change (ports, versions) in defaults; put internal constants the role relies on (package name, config path) in vars. Get this backwards and your role becomes painful to reuse.
$ defaults/main.yml\nhttp_port: 80β lowest β meant to be overridden$ vars/main.yml\npkg_name: httpdβ high β internal constant$ group_vars/web.yml\nhttp_port: 8080β beats the default cleanly
05ansible-galaxy & requirements.yml
You rarely write everything from scratch β Ansible Galaxy hosts community roles and collections you can install. Pin exactly what a project needs in a requirements.yml and install it all in one command, so every teammate and CI runner gets the same versions. Where the content lands is governed by roles_path and collections_path in ansible.cfg (defaults include ./roles and ~/.ansible). Treat requirements.yml like a lockfile: it makes a project reproducible.
$ ansible-galaxy role install geerlingguy.nginxβ grab one role$ ansible-galaxy install -r requirements.ymlβ install everything pinned$ ansible-galaxy collection install ansible.posixβ grab a collection
06Dependencies & collections (FQCN)
meta/main.yml can declare role
dependencies:β those roles run before this role, so a webserver role can depend on a baseline role and trust it has already run. Collections are the bigger packaging unit: they bundle roles, modules, and plugins under a namespace. You reference content from a collection by its Fully-Qualified Collection Name, namespace.collection.module β for exampleansible.posix.firewalld. Acollections:key on a play lets you use short names, but FQCN is unambiguous and is what the exam expects.$ meta/main.yml\ndependencies:\n - role: baselineβ runs before this role$ - ansible.posix.firewalld:\n service: httpβ module by FQCN$ collections:\n - ansible.posixβ play-level short names
Quiz β answers
- Which role subdir is auto-loaded as the role's main task list?
- βtasks/main.yml β Ansible runs this automatically when the role is applied.tasks/main.yml is the entry point Ansible loads for the role's work. handlers/main.yml holds notified handlers, meta/main.yml holds metadata and dependencies, and vars/main.yml holds high-precedence variables β none of those are the task list.
- You want a role variable users can easily override from inventory. Put it in defaults/ or vars/?
- βdefaults/main.yml β it is the lowest precedence in Ansible, so inventory, group_vars, play vars, and -e all beat it cleanly.defaults/main.yml is the lowest-precedence source of all, designed to be overridden. vars/main.yml is HIGH precedence and is hard to override, so it's the wrong place for anything a user should tune.
- What does
ansible-galaxy init webserverdo? - βScaffolds the standard role directory skeleton (tasks/, handlers/, templates/, files/, vars/, defaults/, meta/) under roles/webserver/.
initcreates an empty role with the standard layout already in place, each subdir holding a stub main.yml. Installing a published role is a different command,ansible-galaxy role install NAME. - import_role vs include_role β what's the difference?
- βimport_role is static (parsed at parse time, so tags apply to all its tasks); include_role is dynamic (evaluated at runtime, so it can be looped or made conditional).Static import_role is resolved when the playbook is parsed, so tags and when on the import apply to every task inside. Dynamic include_role is resolved at runtime, which is what lets you loop over it or guard it with a condition β at the cost of tags not propagating the same way.
keep going β these pair well with what you just learned.
Ansible control node & inventory
Ansible is agentless β one control node pushes work to a fleet over SSH. Install ansible-core, write an inventory with groups, ping the fleet, and fire ad-hoc commands. RHCE-ready.
Ansible playbooks & YAML
Plays, tasks, and idempotency. Watch a playbook run task-by-task β ok, changed, skipped β then run it again and watch everything go green with 0 changed. RHCE-ready.
Ansible core modules
file, user, copy, dnf, service β the modules that do the real work. Declare the desired state and let Ansible converge to it, idempotently. RHCE-ready.