Ansible Roles: Create / Use Roles for Configuration Management

Ansible Roles: Create / Use Roles for Configuration Management. Ansible roles are a collection of files, tasks, templates, variables, and modules. They are a modular and reusable way to structure playbooks, making it easier to manage complex configurations and deployments.

If you use a playbook to deploy a web server across several servers. Then, you’d write an Ansible playbook with all the installation and configuration steps for the web server software. This method is repetitive and messy, especially if you want to reuse this playbook for other server deployment. This is where roles come into the picture. In this tutorial, we’ll dive into Ansible roles, exploring their structure, usage, best practices, and practical examples to reinforce your understanding.

Ansible Roles Core Concept

The core concept of Ansible roles is to organize and structure automation tasks into reusable and modular units. Roles encapsulate specific functionalities, configurations, and tasks related to managing a particular component of the infrastructure. This promotes code reuse, modularity, and maintainability in Ansible playbooks.

Here are the core concepts of Ansible roles:

  • Modularity: Roles break down complex automation tasks into manageable units, each representing a specific component or function within the infrastructure.
  • Reusability: Roles are reused across different playbooks and projects, promoting efficiency and consistency in infrastructure automation.
  • Organization: Roles organize related tasks, variables, files, and templates into a standardized directory structure, making it easier to navigate and manage automation projects.
  • Encapsulation: Roles encapsulate the details of implementation within their directories, abstracting away complexity and promoting a clear separation of concerns.
  • Parameterization: Roles support parameterization, allowing customization and flexibility in configuration management by accepting variables at runtime.
  • Idempotence: Ansible roles are designed to be idempotent, ensuring that applying the same role multiple times results in the same desired state.

Basic Structure of Ansible Roles

Ansible Roles are used to break down complex configurations into smaller, manageable pieces, promoting modularity and reusability. Ansible roles follow a specific directory structure to maintain consistency and make it easy for users to understand and work with roles.

Here are the key directories of the Ansible structure:

  • defaults: Contains default variables for the role.
  • files: Holds static files that need to be copied to the target hosts.
  • handlers: Defines handlers – tasks triggered by other tasks.
  • meta: Contains information about the role’s author, description, and related details.
  • tasks: Contains the main tasks of the role.
  • vars: Stores variables used by the role.

Install and Configure the Nginx Web Server Using Ansible Roles

In this example, we create a simple Ansible role named webserver to install and configure Nginx on the target node. We use the following directory structure to achieve this:

├── deploy_nginx.yml
└── webserver
    ├── defaults
    │   └── main.yml
    ├── files
    │   └── index.html
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   ├── configure_nginx.yml
    │   ├── install.yml
    │   └── main.yml
    └── vars
        └── main.yml

Create a Directory Structure

First, create a main directory named roles to hold all files and directories.

					mkdir roles

Next, create a simple Ansible role named webserver inside the roles directory.

					mkdir roles/webserver

Then, create other child directories inside the webserver directory.

					mkdir roles/webserver/{defaults,files,handlers,meta,tasks,vars}

Define Default Role Variables

Roles can have variables associated with them to make them more flexible.

Inside the defaults/main.yml file, you define default variables for your role. Ansible  automatically loads these variables when the role is used in a playbook.

For example, create a main.yml file inside the defaults directory:

					nano roles/webserver/defaults/main.yml

Add the following variable to define the Nginx webserver configuration directory:

# defaults file for nginx webserver
nginx_conf_file: "/etc/nginx/sites-enabled/default"

These variables can be overridden in playbooks if needed.

Next, create a main.yml file inside the var directory to define variables specific to the role. This file is typically used to store variables that are not intended to be overridden and are considered as default values for the role.

					nano roles/webserver/vars/main.yml

Define the variable for the webserver package, service, document directory path, and port:

# vars file for nginx webserver
package_name: "nginx"
service_name: "nginx"
document_root: "/var/www/html"
nginx_port: "8080"


Create a Web Page For Nginx

The files directory contains the static HTML content you want to copy to the remote node. Let’s create an index.html file inside the files directory.

					nano roles/webserver/files/index.html

Add the following HTML code.

<h1>How to use Ansible roles with practical examples!</h1>

This file will be copied to the remote node at the location specified by {{ document_root }} in your variables.

Install and Configure Nginx

The tasks is a directory within an Ansible role is where you define the tasks that should be executed when the role is applied. These tasks could include things like installing packages, configuring files, setting up services, etc.

First, create an install.yml file to install the Nginx package using the variables defined earlier.

					nano roles/webserver/tasks/install.yml

Add the following content.

- name: Install nginx webserver package
  apt: name={{ package_name }} state=latest

Next, create a configure_nginx.yml file to configure Nginx.

					nano roles/webserver/tasks/configure_nginx.yml

Define the Nginx configuration tasks as shown below:

- name: Copy index.html file to remote node
  copy: src=files/index.html dest={{ document_root }}
  - restart and enable nginx service

- name: Change nginx port to 8080
    path: "{{ nginx_conf_file }}"
    regexp: '80'
    replace: '8080'
  - restart and enable nginx service

In the above configuration, the first task uses the copy module to copy the index.html file from the files/ directory to the specified destination on the remote node. The notify section is used to trigger a handler named “restart and enable nginx service” after the copy task is executed. The second task uses the replace module to replace the default Nginx port 80 with 8080 in the Nginx configuration file.

Next, create a main.yml file to refer to both files.

					nano roles/webserver/tasks/main.yml

Add the following content.

# tasks file for nginx webserver
- import_tasks: install.yml
- import_tasks: configure_nginx.yml


Create a Handlers

Handlers are a way to trigger specific actions, such as restarting a service, only when specific events occur during the execution of a playbook. Handlers are defined in the handlers directory within an Ansible role.

Let’s create a main.yml inside the handlers directory.

					nano roles/webserver/handlers/main.yml

Add the following content.

# handlers file for nginx webserver
- name: restart and enable nginx service
  become: true
    name: "{{ service_name }}"
    state: restarted
    enabled: yes


In this example, the “restart and enable nginx service” handler is defined to restart and enable the Nginx service when it is notified.

Create a Metadata

Define the metadata for your Ansible role in the meta/main.yml file. This metadata is commonly used when sharing roles on Ansible Galaxy or for providing information about the role’s author, description, and related details.

Let’s create a main.yml file inside the meta directory.

					nano roles/webserver/meta/main.yml

Add your metadata information:

  author: Hitesh Jethva
  description: Role to deploy nginx web server on Ubuntu
  company: 4sysops


Create a Deployment File

Let’s create a main playbook deployment file to use the webserver role and deploy the Nginx web server on your remote worker node.

					nano roles/deploy_nginx.yml

Add the following content to define your remote node and webserver role.

 - hosts: node1
   become: yes
     - webserver


This playbook assumes that you have a corresponding Ansible role named webserver that you want to apply to the specified host.

Run the Deployment Playbook

Before running the playbook, navigate to the roles directory and check the syntax of your webserver role using the following command.

					cd roles
ansible-playbook deploy_nginx.yml --syntax-check

If everything is fine, you will see the following output.

					playbook: deploy_nginx.yml

Now, run the deploy_nginx.yml playbook to install Nginx on the target node.

					ansible-playbook deploy_nginx.yml

This will install and configure the Nginx web server on the target node:

To test the Nginx installation, open your web browser and type the URL http://your-target-node-ip:8080/index.html. You will see your HTML web page on the following screen.

Ansible Roles: Create / Use Roles for Configuration Management Conclusion

In this tutorial, we have used Ansible roles to install and configure the Nginx web server on the target node. The role-based organization not only simplifies the automation process but also enhances the scalability and maintainability of the system. By abstracting the configuration details into reusable roles, administrators can quickly deploy Nginx across multiple servers, ensuring consistency and reducing the risk of configuration drift.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Would love your thoughts, please comment.x