Ansible roles for configuring Apache Webserver and HAProxy LoadBalancer

Ansible roles are used to simplify Ansible playbook which means we can break a complex Ansible playbook in independent and reusable roles that are used to automatically load certain var_files, tasks, and handlers as per pre-defined file structure. We can call the roles in any Ansible playbook as it is reusable and independent of each other. We can also share the configuration template using roles easily. As mentioned roles need a standardized file structure that means at least one of the directories exists and must have a main.yml however we can remove other directories if not in use. The default location of roles is “/etc/ansible/roles”.

We have a command ‘ansible-galaxy init <ROLE_NAME>’ to create a role skeleton for us. It creates pre-defined directories structure and files as below:


$ ansible-galaxy init nginx_role

Explanation: In the above example, we have created a role called ‘nginx_role’ and used tree command to see the directories structure of the newly created role. Most of the directories have main.yml file that works as the entry point for correspondence directories of the role.

Functions of Ansible Roles

Let’s understand the functionality of each folder :

  • Tasks: We keep our tasks or the plays that will be performed by the roles however we can keep tasks in other folders separately as well for readability and better manageability and can be added to the roles using include if required. If this directory is being used in the role then it must contain main.yml.
  • Vars: It stores variables that are used within the roles. It has the highest level of precedence and we can only override by passing variables via the command line (CLI). It also has a main.yml file.
  • Defaults: It also stores the variables but default variables that mean it supposed to be changed while running the play however role is going to use the default variable if it is not defined or passed. It has the lowest level of precedence.
  • Handlers: It contains handlers that may be flagged to run using the notify keyword, notify keyword-only flags the handler if a task makes changes and handler will be triggered only once besides notified by multiple tasks. It is not only used by the same roles in which it defined but anywhere outside that role.
  • Files: The file directory contains static files that can be deployed via this role. It does not contain var files or templates as it is for simple ordinary files. We can reference the files within this directory without the path. It does not have the main.yml file in it.
  • Templates: It contains templates that we can deploy via this role. It does not have the main.yml file as well.
  • Meta: We can configure role dependencies and other configurations such as allow_duplicates etc.

What is HAproxy ?

HAProxy is a free, amazingly fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP-based applications. It is particularly suited for extremely high traffic web sites and powers quite a number of the world’s most visited ones. Over the years it has become the de-facto standard opensource load balancer, is now shipped with most mainstream Linux distributions, and is often deployed by default in cloud platforms. Its mode of operation makes its integration into existing architectures very easy and riskless, while still offering the possibility not to expose fragile web servers to the internet.

Task Description :

Create an ansible role myapache to configure Httpd WebServer.

Create another ansible role myloadbalancer to configure HAProxy LB.

We need to combine both of these roles controlling webserver versions and solving challenge for host ip’s addition dynamically over each Managed Node in HAProxy.cfg file.

Let’s jump into the task:

Let’s create a folder and set the roles path in the ansible configuration file,

Let us create two ansible roles:

Let us configure the myapache role,

The variables used here are fetched from vars directory’s main.yml file:

Let’s move on to ”myloadbalancer” role to configure haproxy,

The variables used here are fetched from vars directory’s main.yml file,

Now, let’s configure the haproxy config file,

Here we are using jinja2 embedded code for dynamically fetching the new webserver IP with HAproxy loadbalancer.

Now let’s jump ahead to testing the roles we just created,

We successfully completed the task. We can verify it by running the web page.

We can notice the IP is switching even though the IP address which we are using at browser is same. This proves that the HAproxy is working fine.

Now, let’s add one more IP address into the inventory file to check the handler added into the myloadbalancer role is working or not.

Let’s run the playbook again and check if the HAProxy server automatically adds the new target node in its configuration file or not.

Here, we can the tasks are changed for the new target node. Now, let us visit the HAproxy once again and check if it has recognized and updated its configuration file with the new target node or not.

From the output , we can see that IPs are switching, which means that the extra target node is also automatically added in the configuration file of HAproxy and new web page also copied into the target node.

GitHub URL: ARTH-Program/Ansible roles for configuring Apache Webserver and HAProxy LoadBalancer at main · gursimarh/ARTH-Program (

GDSC | IBM Z | GoogleCloudReady Facilitator | Dexterous Photographer | Quantum Computing Enthusiast | ARTH | IIEC Rise | MLOps