Ansible Roles
Ansible role is an independent component that allows the reuse of common configuration steps. The role helps us in breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse. This way you can logically break the playbook into reusable components.
Roles let you automatically load related vars, files, tasks, handlers, and other Ansible artifacts based on a known file structure.
Role Directory
A role directory structure contains directories: defaults, vars, tasks, files, templates, meta, handlers. Each directory must contain a main.yml file that contains relevant content. Let's look a little closer at each directory.
defaults: contains default variables for the role. Variables in default have the lowest priority so they are easy to override.
vars: contains variables for the role. Variables in vars have higher priority than variables in the defaults directory.
tasks: contains the main list of steps to be executed by the role.
files: contains files that we want to be copied to the remote host. We don't need to specify a path of resources stored in this directory.
templates: contains file template which supports modifications from the role. We use the Jinja2 templating language for creating templates.
meta: contains metadata of roles like an author, support platforms, dependencies.
handlers: contains handlers that can be invoked by "notify" directives and are associated with service.
How do we create Ansible Roles?
To create Ansible roles, use the ansible-galaxy command which has the templates to create it. This will create it under the default directory /etc/ansible/roles and do the modifications else we need to create each directory and files manually.
ansible-galaxy init dummy
Where ansible-galaxy is the command to create the roles using the templates.
Init is to initialize the role.
Above command will generate a directory structure as below:
An Ansible role has a defined directory structure with eight main standard directories. As you can see, variables will be stored under vars directory, handlers under handler directory and so on.
Example
Consider below playbook:
- name: this is our 1st play.
hosts: webserver1
tasks:
- name: "task 1"
command: touch /tmp/php_play_1_task_1.txt
- name: "task 2"
command: touch /tmp/php_play_1_task_2.txt
- name: this is our 2nd play.
hosts: webserver1
tasks:
- name: "task 1"
command: touch /tmp/web_play_2_task_1.txt
- name: "task 2"
command: touch /tmp/web_play_2_task_2.txt
- name: this is our 3rd play.
hosts: sqlserver1
tasks:
- name: "task 1"
command: touch /tmp/sql_play_3_task_1.txt
- name: "task 2"
command: touch /tmp/sql_play_3_task_2.txt
In the first play we are installing PHP on remote machine webserver1, web app on webserver2 and installing SQL and starting its services on sqlserver.
Creating the Roles
We have created 3 roles in present working directory as follows:
Now, in php roles, we have defined only tasks which contain main.yml:
And, similarly for webserver and sqlserver-
Now, lets create a playbook which will use one of the above task:
- name: this is our 1st play.
hosts: webserver1
roles:
- webserver
It has only roles'' parameter. Here, there is no need to mention any variables and all as the role 'webserver' that we created in the last step has taken care of all the things.
After running the above playbook:
It has created both the files that we specified in the tasks:
Similarly, if you want that the webserver should also have PHP installed in it, make the below modifications to your playbook:
- name: this is our 1st play.
hosts: webserver1
roles:
- php
- webserver
Running the above playbook again:
It has executed both the tasks of webserver and php respectively.
In the same way, one can also include the sqlserver role to get it installed on the same machine.