Configuring HAproxy and Httpd Over AWS Using Ansible Roles

Using AWS EC2 instnaces and Dynamic Inventory

Ranga Mani kumar
7 min readMar 28, 2021

Introduction:

Ansible

Ansible is a open-source tool provided by Redhat for automating configuration management, cloud provisioning, application deployment, intra-service orchestration and many more IT works. It was written by Michael DeHaan. The code of Ansible Modules mainly written in Python, Shell, Ruby. Ansible is a declarative language, we just have to tell what to do. It is agentless, connecting remotely via ssh to do its tasks.

Load Balancer

Load Balancer is a device which works as a Reverse Proxy and manages the traffic from the clients across the multiple servers. But What is Reverse Proxy ? It is a program which takes the request from the clients and sends it to the server on the behalf of client, the output from the server is sent to the reverse proxy and reverse proxy sends to the client.

HAProxy

HAProxy, High Availability Proxy, is a open source software which provides Load Balancer and Proxy server for TCP/HTTP based applications. It works on Round Robin Algorithm which sends the request to backend servers turn by turn and distributes equally.

Ansible Roles

Role is a concept which provides us a framework where we can organise our playbook in different files for tasks, variables, handlers etc. In playbook, we have to mention everything inside playbook and we have to specify path for variable files if you have created but for roles you don’t need to specify path. It’s by default get to know different things like variables, handler, files etc.

Task

  • 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.

For dynamic inventory you can refer my previous blog from this link

Step-1 :

Let’s create 3 Ansible roles

  • myec2instances
  • myapache
  • myloadbalancer
ansible-galaxy role init <role_name>

Step-2 :

Let’s give roles path and other details regarding to AWS in ansible.cfg file. Here I have created roles in /ws8/roles/ directory.

Step-3 :

Let’s give all details for launching new instances.

Here comes the role speciality, we can give all the tasks in tasks and variables in vars directory inside the created role. We don’t need to specify path

I created variables for all needed parameters and assigning values in the variables file inside the vars. We assign variable values to the parameters using jinja syntax. You get all this values for required paramaters from your AWS account.

Here I gave tags to Instances with key= Name, Value=loadbalancer (for haproxy) and Key=Name, Value=webserver

Here I paused it for 100 seconds after launching instances for letting them complete launching and refresh inventory. Here we are going to use dynamic inventory.

Step-4 :

We can give all tasks in main.yml of tasks directory, haproxy config file in files directory and variable for port number in main.yml of vars directory.

Configuring HAproxy for Loadbalancer using Ansible role named myloadbalancer :

First, we have to install HAproxy software. We use package module of Ansible to install. Ansible can only tell to the yum to install the software. Yum is the command who goes to the location of software and install it.

- name: "Installing haproxy"
package:
name: haproxy
state: present

Then we have to configure HAproxy configuration file i.e., haproxy.cfg. In this file we have to provide port number to bind. Through this port only clients will connect. Then we have to provide backend IP Address, port number as shown in below fig. But in this dynamic world, the IP Address changes anytime and it is not good to do it manually. So we use Python Jinja2 convention and we write code for it and the IP Address will automatically updated according to the dynamic inventory file while running playbook. Using tag_Name_webserver. This will retreive all the IPs of with tag Name=webserver.

Here I have given port_number variable in jinja syntax as it automatically update the value of port_number variable. We can give variable value in main.yml of vars directory.

We have to copy this Python Jinja2 convention configuration file with .j2 extension using template module to the Load Balancer.

- name: "Copying haproxy configuration file"
template:
src: <path>/haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: Restarting haproxy

Here we use notify to notify handler part to restart the service whenever there is a change in the configuration file. Here the handler part, we give in handler directory. So that it is easy to organise the different parts of playbook inside the role.

We have to make SELinux permissive using selinux module.

- name: "Making SElinux permissive"
selinux:
policy: targeted
state: permissive

All part is done, now we have to start the haproxy service using service module. It will start the service on port_number.

- name: "Starting haproxy service"
service:
name: haproxy
state: started
Tasks file for myloadblancer role

Here I take port number 8080

Variable file for myloadblancer role
haproxy.cfg.j2 file for myloadbalancer role

Here I use handlers to run this block whenever notify notifies to this handlers. You can see in step-2 that I used notify. It will notifies to this handler part as configuration changes and it will restart the service.

Handler file for myloadbalancer role

Then our task of Configuring Load Balancer complete.

Configuring backend server httpd using ansible role named myapache :

Step-5 :

Now go to myapache role and give all tasks in main.yml of tasks directory and web page file m.php in files directory.

Step-5 :

Now, We have to install the httpd software using package module in the same way as we did for HAproxy using Ansible.

tasks:
- name: "Installing httpd software"
package:
name:
- httpd
- php

Here, we are also installing php as we use php in our web page.

Step-6 :

Now, we have to copy the web page to the default root directory /var/www/html using template module. We can also create our own directory and customise it. But here Iam using default location of httpd.

- name: "Copying web page"
template:
src: "<path>/m.php"
dest: "/var/www/html/m.php"

Here I copied m.php file

<pre>
<?php
print "<br/>";
print `/usr/sbin/ifconfig`;
?>
</pre>

This is the last step where we have to start the httpd service using service module.

Now all process of configuration is done, Now we just need to create a playbook and use this 3 roles. That all will launch the ec2 instances and configure and set up the HAProxy Load Balancer with Backend server.

Now have to run this playbook, here I used -b option for activation privilage escalation

Lets’s see how it worked by seeing demo pictures.

Launched 2 aws ec2 instances with tags Name=webserver and Name=loadbalancer.
Configured Loadbalancer
Configured Httpd
Instances launched

We can connect but here we are using Load Balancer IP Address and port number 8080 to connect to the web server.

Here you can see I connected with my Load Balancer IP Address with port number 8080 and it is showing the IP Address of one of the backend webserver.

As soon as I refresh, you can see as it is showing the IP Address of my second webserver.

You can get my code from my github repo link

Thankyou…

Keep learning….

Keep sharing…

--

--