We have covered all the essential Ansible topics on our site. Now in this article, let us learn what are ansible roles and how to use Ansible roles to create a structured project and distribute them. Next we will move on to discuss the advantages of using ansible roles over standard playbooks. Finally, we will see how to create Ansible roles and different methods to import roles in the playbook.
Table of Contents
What is Ansible Role?
Ansible roles offer a directory structure where you can break down complex playbooks into small and manageable chunks. The main advantage of using ansible roles is given below:
- You can achieve a great level of modularity.
- Redistribute the roles easily using ansible collections.
- Easy to debug any errors.
- Test-driven approach.
In the upcoming sections, I will show you how to create a simple ansible role and different ways to use roles in the playbook.
Create an Ansible Role
Use the ansible-galaxy
command to initiate the role. Here, I named my role as sample-role.
$ ansible-galaxy init sample-role - Role sample-role was created successfully
Under the sample-role
directory, you will have different directories to organize your playbooks.
Let’s go over each directory to understand its purpose.
- Defaults - You can organize the default variables under this directory.
- Files - Any files you want to copy to managed nodes to be stored under the files directory.
- Handlers - Handler tasks should be grouped under the handlers directory.
- Meta - Stores metadata about the role. It contains metadata like author, version, platform, tags, dependencies, etc.
- Tasks - The playbook tasks should be created under the tasks directory. This is a mandatory directory for roles.
- Templates - Files that will be used for templating should be stored under the templates directory. Files should use the jinga2 extension(.j2).
- Tests - Test cases should go under the test directory.
- Vars - Variables associated with this role. Takes higher precedence if the same variable is used in the defaults directory.
If you look at the above image, one common file under some of the directories is main.yml
. You should not try to rename this file since ansible will look out for the related object under the main.yml
file.
As part of your role, only the tasks directory is mandatory and all other directories can be skipped.
Create Your First Ansible Role
I am going to create a project which will install a couple of tools for my Ubuntu desktop. First, I will create ansible.cfg
file and the inventory file.
$ vim ansible.cfg [defaults] [defaults] inventory = hosts host_key_checking = False nocows = 1 actions_warnings = False interpreter_python = auto_legacy_silent
$ vim hosts localhost ansible_connection=local
Created the playbook with a single task to install terminal tools.
--- - name: Role testing hosts: localhost gather_facts: false become: true tasks: # Tools for terminal - name: TERMINAL - Kitty, Tmux, Fish ansible.builtin.apt: pkg: - kitty - tmux - fish state: present
Below is the output for the above task. This is the standard way of creating a playbook in ansible.
Now let's create a role and organize the task inside the role. I am not using the ansible-galaxy
command to initialize the role, instead I am manually creating the task directory which is the only directory required for my role.
Here my role is named "tools
" and the tasks directory along with the main.yml
file is created.
$ mkdir -p roles/tools/tasks/ $ touch roles/tools/tasks/main.yml $ tree roles/ roles/ `-- tools `-- tasks `-- main.yml 2 directories, 1 file
Now move the task under the tasks/main.yml
file.
In the main playbook, you have to tell ansible to use the roles to run the task. There are a couple of ways to achieve this.
1. Roles At The Play Level
You can use the roles
keyword and give the role name as input.
--- - name: Role testing hosts: localhost gather_facts: false become: true roles: - tools
Ansible will treat the roles defined at play level as static import and will be parsed when parsing the playbook.
You can run the playbook with verbose to see from where the task is automatically picked from.
$ ansible-playbook -K playbook.yml -vvvv
You can add more than one rule under the roles section.
roles: - roleA - roleB - roleC
You can also apply other ansible directives like vars
, and tags
. For example, if you apply tags at the role level they will be inherited by all the tasks under the role.
roles: - role: tools tags: terminal
2. Importing Roles At The Task Level Using Imports & Includes
You can import the roles into the playbook statically and dynamically using the import_roles
and include_roles
directives.
Both the import_role
and include_role
have similar syntax. The main difference is import*
directives are processed during playbook parsing and include*
directive is processed only in the order they are defined and run the task dynamically.
tasks: - name: Import tools tasks import_role: name: tools tasks: - name: Include tools tasks include_role: name: tools
Now you should have a fair understanding of how to structure a role. When you create playbooks that involve variables, handlers, and files then you have to create an appropriate directory and group the tasks.
Ansible Role Location
Ansible has it’s method to find the role location and run the tasks. If ansible is not able to locate the role, then the following error will be thrown.
ERROR! the role 'tools' was not found in /ansible/dockerlab/playbooks/roles_testing/project1/roles:/home/ansuser/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:/ansible/dockerlab/playbooks/roles_testing/project1
Take a look at the above error message. It shows a couple of directories where ansible will search for the role.
The first and last directory path is automatically added by ansible based on the directory from which you ran the playbook.
- First the roles will be searched under the
roles/
directory. The roles directory should be in the same directory as your main playbook. - Under the home directory
~/.ansible/roles
. - Under the default system directories
/usr/share/ansible/roles
,/etc/ansible/roles
. - Under the project directory.
If you have stored the roles in a different location, then you can set the path using "roles_path
" in ansible.cfg
file.
#ansible.cfg [defaults] roles_path = <path-to-roles>:
Conclusion
In this article, we have seen what are ansible roles and the advantages of using ansible roles over standard playbooks. And then we discussed how to create Ansible roles and different ways to import ansible roles in the playbook. Finally, we have seen how ansible finds the roles using the roles_path
and how to add the custom path to the roles_path
directive.