Home Ansible Ansible Roles Tutorial For Beginners

Ansible Roles Tutorial For Beginners

How To Effectively Structure A Project Using Ansible Roles

By Karthick
Published: Updated: 5.9K views

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.

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.

Role Directory Structure
Role Directory Structure

Let’s go over each directory to understand its purpose.

  1. Defaults - You can organize the default variables under this directory.
  2. Files - Any files you want to copy to managed nodes to be stored under the files directory.
  3. Handlers - Handler tasks should be grouped under the handlers directory.
  4. Meta - Stores metadata about the role. It contains metadata like author, version, platform, tags, dependencies, etc.
  5. Tasks - The playbook tasks should be created under the tasks directory. This is a mandatory directory for roles.
  6. Templates - Files that will be used for templating should be stored under the templates directory. Files should use the jinga2 extension(.j2).
  7. Tests - Test cases should go under the test directory.
  8. 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.

Install Terminal Tools
Install Terminal Tools

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.

Contents of main.yml File
Contents of 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
Run Playbook with Verbose
Run Playbook with Verbose

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.

  1. First the roles will be searched under the roles/ directory. The roles directory should be in the same directory as your main playbook.
  2. Under the home directory ~/.ansible/roles.
  3. Under the default system directories /usr/share/ansible/roles, /etc/ansible/roles.
  4. 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.

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. By using this site, we will assume that you're OK with it. Accept Read More