Skip to content
Mohit edited this page Aug 16, 2017 · 1 revision

In the test/vagrant4 we saw how we were able to declutter the main playbook.yml file. However, remember that we ended up with 4 different files whose combined effect was just to run a ghost blog behind Nginx reverse proxy. Imagine you trying to do it for your entire infrastructure's configuration... soon it will become impossible to manage all those files.

Roles adds another layer of abstraction making it convenient for us to install/ manage packages in their own isolated world and can be easily shared among server groups or even throughout the infrastructure.

Roles automatically loads the main.yml file inside specific and a well-known file-structure. The file structure looks something like this:

playbook.yml
ansible.cfg
hosts
roles/
   ghost/
     tasks/
     handlers/
     files/
     templates/
     vars/
     defaults/
     meta/
     README.md
   nginx/
     tasks/
     defaults/
     meta/
     ...
     ...

Instead of making this folder structure manually, you can ask ansible-galaxy to do it for you. You can use the command ansible-galaxy init <rolename>

Each of the sub-directories inside of roles contain main.yml which is always included without you having to explicitly ask for.

Let's first look at two main directories which are crucial in making your role work:

meta:

If you created the above directory structure using ansible-galaxy command, then you already have a main.yml file inside meta directory. This directory basically contains all the meta information for your role. You can neglect almost every field for now and simply scroll to the bottom and look for dependencies: [].

dependencies basically provides a convenient way for you to ask Ansible to run a role or multiple roles before actually running the role. To see an example check the role for installing ghost [test/vagrant5/roles/https://github.com/Mohitsharma44/ansible-playbooks/blob/master/test/vagrant5/roles/ghost/meta/main.yml]. Before we run this role, we want to make sure that node and npm are correctly installed! So we add the line:

---
...
...
dependencies:
- {role: nodejs}

tasks

As the name suggests, this directory contains tasks. All the tasks should be either inside main.yml or included inside main.yml.

Other directories are:

  • handlers - contains handlers, which may be used by the current role or even outside the role.
  • defaults - default variables for the role (we'll talk about this a bit later)
  • vars - other variables for the role (we'll talk about this a bit later)
  • files - contains files which can be deployed via this role (generally used for copying them to remote)
  • templates - contains jinja2 template files

You can explore all the above in the 3 roles in test/vagrant5 setup

Using roles must be pretty clear by now... however if you notice keenly, you'll observe that we have two directories defaults and vars that talk about containing variables and not to mention the variables directory inside the root folder with playbook.yml file. So where should you put all the variables? Which directory will take precedence over the other?

Variable precedence

This is generally confusing to the first-time users of Ansible roles. I know it took me a fair bit of reading to completely understand the variable precedence. Ansible's official documentation on variable precedence does a great job at explaining it. I will talk about it in a more direct form that is applicable to us at this stage.

So this is the hierarchy in which the precedence of variables can be explained:

  • --extra-vars (commandline, highest precedence)
  • root/vars -- variables defined in either playboook or included from another yml file.
  • roles/vars -- variables defined in the roles vars/main.yml
  • roles/defaults or the variables defined in the roles default/main.yml