Ansible Roles¶
See roles in Ansible.
Roles are used to organize and reuse playbook content.
Roles are essentially a collection of tasks and their associated resources (variables,
templates, handlers, etc.) packaged together for a specific purpose.
The purpose can be something like configuring a web server or setting up a database.
They're somewhat similar to classes in object-oriented programming.
Table of Contents¶
Role Directory Structure¶
A role has a predefined structure with specific directories for different types of content.
This is what a typical role looks like:
roles/
└── myrole/
├── tasks/ # Contains the main list of tasks to execute
│ └── main.yml # Entry point for tasks
├── handlers/ # Contains handlers (triggered by tasks)
│ └── main.yml
├── templates/ # Contains Jinja2 template files
├── files/ # Contains static files to copy to remote machines
├── vars/ # Contains variable definitions (static)
│ └── main.yml
├── defaults/ # Contains default variable definitions (can be overridden)
│ └── main.yml
├── meta/ # Contains metadata about the role (dependencies, etc.)
│ └── main.yml
└── tasks/main.yml # Main entry point for the role
tasks/
: Where you define the main tasks for the role.handlers/
: Define handlers that are triggered bynotify
directive intasks
.templates/
: StoreJinja2
templates for dynamically generating files.files/
: Store static files that can be copied to remote hosts.vars/
: Define variables that are specific to the role.defaults/
: Define default values for variables (lowest precedence).meta/
: Include metadata about the role (like depenencies).
Creating and Using a Role¶
Creating a Role¶
You can manually create the directory structure.
You can also use the ansible-galaxy
command:
myrole
under the
roles
directory.
Defining Role Tasks¶
The file roles/myrole/tasks/main.yml
is used to define tasks for the role.
- name: Install NGINX
apt:
name: nginx
state: present
update_cache: yes
- name: Enxure NGINX is started
service:
name: nginx
state: started
enabled: yes
Using a Role in a Playbook¶
Use the name of the role in a playbook using the roles
key.
myrole
role.This runs the tasks and resources defined in the role (
roles/myrole
).
NOTE: If you have a playbook that you're inheriting roles in (as above), any tasks in that playbook will always happen after roles are executed.
If you need tasks to happen before roles, usepre_tasks
instead oftasks
.
Where you can Use Roles¶
-
Playbooks
-
Role dependencies
- Roles can depend on other roles. Define dependencies in
roles/myrole/meta/main.yml
- Roles can depend on other roles. Define dependencies in
-
In the
include_role
task. You can include roles dynamically in a task.
-
In collections. Roles can be part of an Ansible collection.
- This can make them easy to distribute and reuse.
Example of Using a Role in Ansible¶
Directory Structure¶
This is the directory structure for the example:
myproject/
├── roles/
│ └── nginx/
│ ├── tasks/
│ │ └── main.yml
│ ├── handlers/
│ │ └── main.yml
│ ├── templates/
│ │ └── nginx.conf.j2
│ ├── files/
│ ├── vars/
│ │ └── main.yml
│ ├── defaults/
│ │ └── main.yml
│ ├── meta/
│ │ └── main.yml
├── inventory
└── site.yml
Playbook: site.yml
¶
-
Indicates the start of the play.- This will inherit and run all the
tasks
in thenginx
role. - All tasks will be run on the
webservers
hosts defined in theinventory.yml
Role tasks: roles/nginx/tasks/main.yml
¶
- name: Install NGINX
apt:
name: nginx
state: present
- name: Deploy NGINX configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
mode: 0644
- name: Start and Enable NGINX
service:
name: nginx
state: started
enabled: yes
Basic Role Usage¶
-
Create a directory called
roles
:
-
Then initialize a role:
Then a bunch of directories are created.
This can be overwhelming at first but if you just need to run tasks then you only need look at thetasks
directory. -
Look in the
<role_name>/tasks/
directory for a file calledmain.yml
.
Put any tasks you want to run in that file. -
Then, in your playbook:
All the tasks in thatmain.yml
file should be run.
If you need to use variables, templates, etc., there are other directories where you put those (like <role_name>/vars
for variables).
Using Variables to Assign Roles Dynamically¶
If you want to assign roles dynamically based on host variables, you can do:
Then, in your inventory:
[web_servers]
web1 ansible_host=192.168.1.10 assigned_roles=["webserver_role"]
web2 ansible_host=192.168.1.11 assigned_roles=["webserver_role"]
[db_servers]
db1 ansible_host=192.168.1.20 assigned_roles=["database_role"]
db2 ansible_host=192.168.1.21 assigned_roles=["database_role"]
- The
assigned_roles
variable will be used to determine which roles to run on each given host.
Variables with Roles¶
Specify variables to use inside roles in the role-name/vars/main.yml
file.
When defining variables inside a role (roles/role_name/vars/main.yml
), those
variables will only be available inside the role itself. They will not be
accesible in a playbook that calls that roll.
If you need to access variables inside the main playbook, use set_fact
or define
the variable in either the inventory, the playbook vars
section, or a role default.
Example vars/main.yml
:
These vars will then be available anywhere inside the role role-name
:
tasks/
handlers/
templates/
files/
meta/
Conditionally Calling Roles¶
You can set up conditions for roles in playbooks.
To do this, you specify a dictionary inline in the roles section.
role4
.The
role4
role will only be run when the variable myvar
is true
. We're using
a jinja2 filter to make it default to false
if it's not defined.