Ansible Roles Creation | Handlers & Variable Precedence

Ansible Role Creation

In this post, we’ll delve into Ansible role creation using practical examples for setting up HAProxy and web servers. Creating well-structured, reusable Ansible roles is essential for effective automation, especially in complex configurations. We’ll focus on organizing tasks, handlers, variables, and the structure required for making your automation modular and maintainable.

What Are Ansible Roles?

Ansible roles offer a way to break down playbooks into modular components, making automation reusable and manageable. By converting playbooks into roles, the setup becomes adaptable across environments, saving time and effort. Roles are especially useful in multi-tier applications with components like web servers, databases, and load balancers.

Using roles allows tasks, handlers, and variables to be organized in separate, dedicated folders, creating a cleaner structure that simplifies troubleshooting and collaboration. This modular design facilitates teamwork, making roles easy to share and reuse among multiple projects.

Prerequisites for Ansible Role Creation:

To begin, we will use Ansible’s ansible-galaxy init command to generate a structured directory for roles. This command creates folders and essential files under each role, ensuring all components are neatly organized.

Example Folder Structure:

  • defaults/: Contains default variables (main.yml).
  • files/: Stores static files, like configuration templates.
  • handlers/: Holds handlers used to trigger tasks such as service restarts.
  • tasks/: The main section where tasks are listed.
  • templates/: Used for Jinja2 templates, allowing dynamic configurations.
  • meta/: Defines role dependencies.
  • vars/: Holds role-specific variables with higher precedence than defaults

Resources

Step-by-Step: Creating an HAProxy Role

We’ll start by creating a folder for our roles and defining each role under it. Let’s create the HAProxy role.

  • Create the Role Directory:
mkdir -p ansible_roles/roles
cd ansible_roles/roles
ansible-galaxy init HAproxy
  • Set Up the Task File: Navigate to tasks/main.yml in the HAProxy role folder. Add all necessary tasks, formatted with clear indentation, as Ansible will read the tasks directly from this file without needing to specify task keywords.
  • Configuring Handlers: To manage service restarts when configurations change, we define handlers in handlers/main.yml. These handlers will be notified whenever a related configuration file is modified.
  • Templates Folder: Place any Jinja2 templates, like haproxy.cfg.j2, in the templates folder. This allows dynamic configurations using variables.
  • Creating Default Variables: Defaults, such as the load balancer port, can be set in defaults/main.yml.

Implementing the Web Server Role

Next, we’ll create a similar role for the web server. This includes setting up tasks/main.yml with tasks to install and configure the web server, adding templates, and defining variables.

  • Create and Configure the Web Server Role:
ansible-galaxy init webserver
  • Define Dynamic Variables: The web server uses a template (index.html.j2) in the templates/ folder, which can pull dynamic values such as IP addresses from variables.

Calling Roles in a Playbook

With both HAProxy and web server roles ready, we create a playbook to execute these roles:

- hosts: lb
  roles:
  - name: deploy haproxy
    role: haproxy

- hosts: webservers
  roles:
  - name: deploy webservers
    role: webservers

This structure enables organized deployments, with each role functioning independently and reusable across environments.

Using Ansible Variable Precedence

Ansible variables have different precedence levels, allowing flexibility in configurations. Here’s the order of variable precedence (from lowest to highest):

  1. Defaults: Defined in defaults/main.yml.
  2. Role Vars: Defined in vars/main.yml.
  3. Inventory Variables: Defined in the inventory file.
  4. Playbook Variables: Defined directly in playbooks.
  5. Extra Variables: Passed in the command line, with the highest precedence.

For example, the default load balancer port can be set in defaults/main.yml, but if needed, it can be overridden at runtime using the -e option:

ansible-playbook deploy_haproxy_webservers.yml -e "lb_port=80"

Final Execution

After setting up all components, validate the playbook syntax:

ansible-playbook deploy_haproxy_webservers.yml --syntax-check

Then, run the playbook:

ansible-playbook deploy_haproxy_webservers.yml -i inventory

Upon execution, Ansible will install and configure HAProxy and the web server, updating services as needed based on configuration changes.


Creating Ansible roles and understanding variable precedence streamlines your automation tasks and makes your playbooks reusable and organized. By following these best practices, you enhance your project’s maintainability, simplify collaborative efforts, and save time across deployments.


If you’re new to Ansible or looking to dive deeper, check out my Ansible Playlist on YouTube for step-by-step tutorials.


Related Resources:

Ansible Blogs

Complete playlist on Ansible on YouTube Channel.

Leave a Comment

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

Scroll to Top