Skip to main content

Ansible Roles Guide

Ansible Roles provide a way to structure and organize tasks in a modular and reusable way. Roles are a crucial aspect of building clean and maintainable Ansible playbooks, especially when working with larger projects or reusable automation tasks.


1. What is an Ansible Role?​

A role is a collection of Ansible tasks, variables, files, templates, and other resources, all logically organized. Roles allow you to reuse and share common configurations, such as setting up a web server, installing a database, or in the case of your collection, setting up blockchain nodes.

Each role can include:

  • Tasks: A set of actions to execute (e.g., installing packages, configuring services).
  • Handlers: Triggered when notified by tasks (e.g., restarting services after changes).
  • Templates: Jinja2 templates for dynamically configuring files.
  • Variables: Default and optional values that tasks can use.
  • Files: Static files that can be copied to hosts.
  • Meta: Role metadata (e.g., dependencies).
  • Defaults: Default variables used by the role.

Roles are stored in a directory structure that makes it easy to organize resources.


2. Role Directory Structure​

An Ansible role has a specific directory structure to keep tasks and resources organized:

roles/
└── myrole/
├── defaults/ # Default variables
│ └── main.yml
├── files/ # Static files to be copied
├── handlers/ # Handlers for tasks
│ └── main.yml
├── meta/ # Role metadata
│ └── main.yml
├── tasks/ # Main list of tasks to be executed
│ └── main.yml
├── templates/ # Jinja2 templates
├── vars/ # Variables used by this role
│ └── main.yml
└── README.md # Documentation for the role

Key Directories:

  • tasks/: Contains the main list of tasks to run in main.yml.
  • templates/: Contains templates that can be dynamically filled in with variables and pushed to the host.
  • handlers/: Contains tasks triggered by notifications, like restarting services.
  • defaults/: Contains default variables, which can be overridden.
  • vars/: Stores variables specifically for the role.

3. Creating a Role​

You can create a new role manually by setting up the directory structure, or use Ansible’s built-in tool to generate a role skeleton:

ansible-galaxy init myrole

This will create the necessary folders and files for the role.


4. Using Roles in a Playbook​

To use a role in your playbook, you reference it under the roles section. The role is applied to the hosts you specify in the playbook.

Example Playbook:

---
- name: Apply role to configure Nginx
hosts: webservers
become: true
roles:
- nginx

In this example, the nginx role will run on all hosts defined in the webservers group.


5. Variables in Roles​

Roles can make use of variables to make them more flexible and reusable. Variables can be defined in several places:

  • Role defaults: These are the lowest priority and can be overridden by other variables.
  • Playbook variables: Passed in the playbook when the role is used.
  • Host variables: Set per host in the inventory file.

Example Default Variables (defaults/main.yml):

nginx_package: nginx
nginx_service: nginx
nginx_conf_path: /etc/nginx/nginx.conf

These default values can be overridden in the playbook:

- name: Apply Nginx role with custom settings
hosts: webservers
become: true
roles:
- role: nginx
vars:
nginx_conf_path: /custom/path/nginx.conf

6. Tasks in Roles​

Tasks are stored in tasks/main.yml. These tasks define the operations to be performed when the role is applied to a host.

Example Task File (tasks/main.yml):

---
- name: Install Nginx
ansible.builtin.apt:
name: "{{ nginx_package }}"
state: present

- name: Copy Nginx configuration template
ansible.builtin.template:
src: nginx.conf.j2
dest: "{{ nginx_conf_path }}"
notify: Restart Nginx

This example installs the Nginx package and copies a template configuration file. The notify directive triggers the Restart Nginx handler, which will only run if the configuration file changes.


7. Handlers in Roles​

Handlers are defined in handlers/main.yml. These are tasks that run when notified by other tasks.

Example Handler File (handlers/main.yml):

---
- name: Restart Nginx
ansible.builtin.service:
name: "{{ nginx_service }}"
state: restarted

The handler Restart Nginx will only be executed if a task calls it via notify.


8. Templates in Roles​

Templates allow you to use variables to generate dynamic configuration files. They are written in the Jinja2 templating language.

Example Template (templates/nginx.conf.j2):

server {
listen 80;
server_name {{ server_name }};
root {{ document_root }};
}

This template uses the server_name and document_root variables, which can be set in the playbook or the role’s default variables.


9. Example Role: Nginx Configuration​

Here’s a full example of an Nginx role that installs Nginx, copies a configuration file, and starts the service.

Role Directory Structure:​

roles/
└── nginx/
├── defaults/
│ └── main.yml
├── tasks/
│ └── main.yml
├── handlers/
│ └── main.yml
└── templates/
└── nginx.conf.j2

Defaults (defaults/main.yml):​

nginx_package: nginx
nginx_service: nginx
nginx_conf_path: /etc/nginx/nginx.conf
server_name: example.com
document_root: /var/www/html

Tasks (tasks/main.yml):​

---
- name: Install Nginx
ansible.builtin.apt:
name: "{{ nginx_package }}"
state: present

- name: Copy Nginx configuration template
ansible.builtin.template:
src: nginx.conf.j2
dest: "{{ nginx_conf_path }}"
notify: Restart Nginx

Handlers (handlers/main.yml):​

---
- name: Restart Nginx
ansible.builtin.service:
name: "{{ nginx_service }}"
state: restarted

Template (templates/nginx.conf.j2):​

server {
listen 80;
server_name {{ server_name }};
root {{ document_root }};
}

10. Best Practices for Roles​

  • Use Default Variables: Set default values in defaults/main.yml and allow them to be overridden for flexibility.
  • Modularize Tasks: Break large tasks into smaller ones and group them logically.
  • Document Your Role: Include a README.md in the role directory to explain the role’s purpose, variables, and usage.
  • Reuse Roles: Keep roles generic so they can be reused in different projects or contexts.

Conclusion​

Ansible Roles are essential for organizing and reusing tasks in a modular way, making your playbooks easier to maintain, scale, and share. By structuring your automation tasks into roles, you can create cleaner, more efficient playbooks, such as the ones used in the republic.crypto Ansible collection for blockchain infrastructure.