What are Ansible roles and how is it useful?

Ansible roles are a way to organize and package automation tasks into reusable and modular units. A role is a collection of tasks, files, templates, and variables that are grouped together in a predefined directory structure. Roles can be used to break up complex automation tasks into smaller, more manageable pieces, which can be shared and reused across different playbooks.

Each role directory typically contains a main YAML file called main.yml which defines the tasks to be executed for the role, as well as other YAML files for defining variables, files, templates, and other resources used by the tasks. Roles can also include pre- and post-tasks, handlers, and dependencies on other roles.

We have already discussed the Ansible playbook and how to write an Ansible playbook in our earlier articles How to write Ansible playbooks. We normally define tasks inside a single playbook which will be good for a small use case but if we are doing multiple tasks our playbook will become larger and larger and makes more difficult to handle and understand in that cases we split the playbook into multiple roles and each role will consist of various tasks.

Prerequisite

Ansible must already be installed in your system you can refer to our previous article to install Ansible
How to install Ansible on Ubuntu 20.04

In this article, I am going to show how to split a playbook which installs an Nginx webserver and copies contents from the host to the document root into 2 different roles.

First of all, let me show the playbook which is used for this here’s an example Ansible playbook that installs an Nginx web server and copies contents from a directory to the Nginx root directory for serving the contents:

- name: Install Nginx and copy content to root directory
  hosts: localhost
  become: true
  vars:
    nginx_root_dir: /var/www/html
    content_dir: /home/ubuntu/website/index.html

  tasks:
    - name: Install Nginx web server
      apt:
        name: nginx
        state: present

    - name: Copy contents to Nginx root directory
      copy:
        src: "{{ content_dir }}"
        dest: "{{ nginx_root_dir }}"
      notify: Restart Nginx

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

In this example playbook, we define two variables:

  • nginx_root_dir: The path to the Nginx root directory where we want to copy the content by default ginx root directory is /var/www/html/
  • content_dir: The path to the directory where the content that we want to serve is located.

We then have two tasks:

  • Install Nginx web server: This task uses the apt module to install Nginx on the target server.
  • Copy contents to Nginx root directory: This task uses the copy module to copy the contents of the content_dir directory to the nginx_root_dir directory. We also specify a notify parameter to trigger a handler that will restart the Nginx service after the content has been copied.

Finally, we define a handler that will restart the Nginx service when it is notified. This ensures that the new content is served correctly.

For this example, I am running this playbook on localhost so Nginx will be installed on my local system.So that’s it is not a complex playbook just a basic playbook

I have a sample index.html created for this example so after running the playbook using ansible-playbook <playbook_name> you will get a similar response like this.

After running this playbook and browsing localhost within my browser I will get a response similar to this. That is super easy isn’t it

Okay now split this playbook into 2 ansible roles one for installation and the other for copying the contents

Here’s how you can split the original playbook into two separate roles: one for the installation of Nginx and another for copying contents to the Nginx root directory.

For that, we need to create 2 roles using the ansible-galaxy init command

ansible-galaxy init installation
ansible-galaxy init copy

After running this command in your system 2 folders will be created on respected names installation and copy.

This will the directory structure of the created folder.

Oh, wait there are some folders and files created here automatically by the ansible role. Let me explain them to you one by one.

  • defaults: This folder contains the default variables for the role. These variables are used if the user does not provide their own values for these variables.
  • handlers: This folder contains the handlers for the role. Handlers are tasks that are triggered by specific events during the playbook run, such as when a service is restarted or a configuration file is updated.
  • meta: This folder contains metadata for the role, such as the role name, author, description, and dependencies on other roles.
  • README.md: This file contains documentation for the role. It is a good practice to provide a brief description of the role and instructions on how to use it.
  • tasks: This folder contains the main tasks for the role. These tasks define what actions should be performed by the role.
  • tests: This folder contains tests for the role. Tests can be run to verify that the role is working as expected. The inventory file specifies the hosts that the role should be tested on, and the test.yml file contains the test tasks.
  • vars: This folder contains variables for the role. These variables can be used in the tasks or templates.
Role 1: Installation

First, navigate to your installation directory

The installation the role will handle the installation of Nginx. Here we are using the task folder for defining our task and the vars folder for defining our variables.

Open the main.yaml in the task folder and copy this task for installing Nginx.

---
- name: Install Nginx web server
  apt:
    name: nginx
    state: present

Next, open the main.yaml in the vars folder and copy this variable for specifying Nginx root directory.

---
nginx_root_dir: /var/www/html

Role 2: Copy

The copy the role will handle the copying of content to the Nginx root directory.
Here we are using the task folder for defining our task, the vars folder for our variables and the handler folder for defining our handlers

Navigate to your copy folder and Open the main.yaml in the task folder.

This task will handle the copying of content from our content directory to Nginx root directory.

---
- name: Copy contents to Nginx root directory
  copy:
    src: "{{ content_dir }}"
    dest: "{{ nginx_root_dir }}"
  notify: Restart Nginx

Next, navigate to your vars directory and copy and paste these contents inside the main.yaml file.

---
nginx_root_dir: /usr/share/nginx/html
content_dir: /home/ubuntu/website/index.html

The file will is used to define the variables used in your playbook.

Next, navigate into your handlers directory and copy and paste this content in the main.yaml

---
- name: Restart Nginx
  service:
    name: nginx
    state: restarted

This will make sure that the always latest content is served Users are using notify parameter to trigger this handler.

Modifying the playbook

Lastly, we need to modify our original playbook and add the roles.

---
- name: Install Nginx and copy content to root directory
  hosts: localhost
  become: true
  roles:
    - installation
    - copy

In this playbook, we include both the installation and copy roles. Ansible will automatically execute the tasks defined in both roles in the order they are listed in the roles list.

To use this playbook, make sure to create the appropriate directory structure for each role as described above. Once you have the roles defined, you can run the playbook as usual with the ansible-playbook command.

Summary:
In this tutorial, we have learned what is ansible role and how to split a playbook into 2 different roles.

Leave a Reply

Your email address will not be published. Required fields are marked *