Ansible Roles promotes code reusability and provides a simple method for packaging Ansible code in a simple way that can be shared and consumed. An Ansible role is a collection of all the required Ansible tasks, handlers, and Jinja2 templates that are packaged together in a specific structure. A role should be designed in order to deliver a specific function/task. In this recipe, we will outline how to create an Ansible role and how to use it in our playbooks.
Using Ansible Roles
How to do it...
- Inside the ch1_ansible folder, create a new folder called roles and create a new role called basic_config, as shown here:
$ mkdir roles
$ cd roles
$ ansible-galaxy init basic_config
- Update the basic_config/vars/main.yml file with the following variable:
$ cat roles/basic_config/vars/main.yml
---
config_dir: basic_config
- Update the basic_config/tasks/main.yml file with the following tasks:
$ cat roles/basic_config/tasks/main.yml
---
- name: Create Configs Directory
file:
path: "{{ config_dir }}"
state: directory
run_once: yes
- name: Generate Cisco Basic Config
template:
src: "{{os}}.j2"
dest: "{{config_dir}}/{{inventory_hostname}}.cfg"
- Inside the basic_config/templates folder, create the following structure:
$ tree roles/basic_config/templates/
roles/basic_config/templates/
├── ios.j2
└── junos.j2
$ cat roles/basic_config/templates/ios.j2
hostname {{ hostname }}
!
{% for server in ntp_servers %}
ntp {{ server }}
{% endfor %}
- Create a new playbook, pb_ansible_role.yml, with the following content to use our role:
$ cat pb_ansible_role.yml
---
- name: Build Basic Config Using Roles
hosts: all
connection: local
roles:
- basic_config
How it works...
In this recipe, we start by creating the roles directory within our main folder. By default, when using roles, Ansible will look for roles in the following location in this order:
- The roles folder within the current working directory
- /etc/ansible/roles
Consequently, we create the roles folder within our current working directory (ch1_ansible) in order to host all the roles that we will create in this folder. We create the role using the ansible-galaxy command with the init option and the role name (basic_config), which will create the following role structure inside our roles folder:
$ tree roles/
roles/
└── basic_config
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
As can be seen from the preceding output, this folder structure is created using the ansible-galaxy command and this command builds the role in keeping with the best practice role layout. Not all these folders need to have a functional role that we can use, and the following list outlines the main folders that are commonly used:
- The tasks folder: This contains the main.yml file, which lists all the tasks that should be executed when we use this role.
- The templates folder: This contains all the Jinja2 templates that we will use as part of this role.
- The vars folder: This contains all the variables that we want to define and that we will use in our role. The variables inside the vars folder have very high precedence when evaluating the variables while running the playbook.
- The handlers folder: This contains the main.yml file, which includes all the handlers that should run as part of this role.
The role that we created has a single purpose, which is to build the basic configuration for our devices. In order to accomplish this task, we need to define some Ansible tasks as well as use a number of Jinja2 templates in order to generate the basic configuration for the devices. We list all the tasks that we need to run in the tasks/main.yml file and we include all the necessary Jinja2 templates in the templates folder. We define any requisite variable that we will use in our role in the vars folder.
We create a new playbook that will use our new role in order to generate the configuration for the devices. We call all the roles that we want to run as part of our playbook in the roles parameter. In our case, we have a single role that we want to run, which is the basic_config role.
Once we run our playbook, we can see that a new directory called basic_config is created with the following content:
$ tree basic_config/
basic_config/
├── csr1.cfg
├── csr2.cfg
├── mx1.cfg
└── mx2.cfg
See also
For more information regarding Ansible Roles, please consult the following URL:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html