Implementing HaProxy LoadBalancer on AWS Cloud

Akhilesh Jain
7 min readMar 7, 2021

In this Article, I have deployed HaProxy Server and some HTTPD Servers on AWS Cloud using automation tool ‘Ansible’.

This is the 2nd Part of my Task, Link for this Task 1 is as follows:

In this Task, I have used the concept of ‘Dynamic Inventory’.

So, Configuration is same as done in the above mentioned story, but “ec2.py” and “ec2.ini” files are there in some other location, i.e in the hosts folder in my main task folder “Arth_Task12.2”.

Note → Its a request that, reader must see the above mentioned link in which, I have done same setup on AWS, but I have used “Roles” in ansible, but In this Story I have Used a Single Playbook. Every link and all are there.

So, I have downloaded the 2 script files in the following location:

To make these files executable, we have to change the permissions of these files:

Now, I have Configured ec2.py and ec2.ini file. In ec2.py file, We just have to change the First line and write python3 there as shown:

In the ec2.ini file, at the end of file, we have to add the credentials of our IAM user.

To create IAM user, following is the medium story:

For authentication on AWS, I have transferred the private key to my VM which is Arth_Task12.pem, and hence changed permission of this file to 400.

Following is the structure of my Task Folder:

Now, we have to write a configuration file ‘ansible.cfg’, in which we have to mention the key, hosts location and some privileges to the user.

We will create a vault.yml file in which, we have to give the same credentials as given in ‘ec2.ini’ file.

So, we have to encrypt this file:

I have created a file, in which I have written the password of my vault, name of the file is ‘vault_pass_file’.

As we have 2 playbooks, one is used to create the VM’s, and the other is used to configure the VM’s:

  • Setup.yml — This file is to create the VM’s, and following is the code:
---
- name: "Creating 4 VMs and some python libaries"
hosts: localhost
gather_facts: false
vars_files:
- vault.yml
tasks:
- name: "installing boto"
pip:
name: "boto"
executable: pip3
- name: "installing boto3"
pip:
name: "boto3"
executable: pip3
- name: "creating security group"
ec2_group:
aws_access_key: "{{ ak }}"
aws_secret_key: "{{ sak }}"
name: 'launch-wizard-1'
description: 'sg with rule descriptions'
vpc_id: 'vpc-224d514a'
tags:
Name: "task12-sg"
region: "ap-south-1"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
rule_desc: allow all on port 22 for ssh
- proto: tcp
cidr_ip: 0.0.0.0/0
ports:
- 80
rule_desc: allow all on port 80 for webserver
- proto: tcp
cidr_ip: 0.0.0.0/0
ports:
- 2629
rule_desc: allow all on port 2629 for loadbalancer
rules_egress:
- proto: all
from_port: 0
to_port: 0
cidr_ip: 0.0.0.0/0
- name: "Creating LoadBalancer"
ec2:
count: 1
image: "ami-0ebc1ac48dfd14136"
instance_type: t2.micro
region: "ap-south-1"
wait: yes
instance_tags:
Name: Ansible_LoadBalancer
group: "launch-wizard-1"
key_name: "Arth_Task12"
state: present
aws_access_key: "{{ ak }}"
aws_secret_key: "{{ sak }}"
- name: "webserver"
ec2:
count: 3
image: "ami-0ebc1ac48dfd14136"
instance_type: t2.micro
region: "ap-south-1"
wait: yes
instance_tags:
Name: Ansible_WebServer
group: "launch-wizard-1"
key_name: "Arth_Task12"
state: present
aws_access_key: "{{ ak }}"
aws_secret_key: "{{ sak }}"
  • playbook.yml — This file is used to configure the VM’s, following is the code written in this file.
---
- name: Deploying HTTPD Servers
hosts: tag_Name_Ansible_WebServer
tasks:
- name: install httpd
package:
name: "httpd"
state: present
- name: copy content
copy:
content: "Arth Task12.2 Successfully completed\n, Hello from {{ ansible_hostname }}({{ ansible_default_ipv4['address'] }})"
dest: /var/www/html/index.html
notify: restart service
- name: service httpd start
service:
name: "httpd"
state: started
enabled: yes
handlers:
- name: restart service
service:
name: "httpd"
state: "restarted"
- name: Deploying HaProxy Server
hosts: tag_Name_Ansible_LoadBalancer
tasks:
- name: "Installing Haproxy"
package:
name: "haproxy"
state: present
- name: Copying Configuration file
template:
src: "haproxy.j2"
dest: "/etc/haproxy/haproxy.cfg"
notify: "restart service"
- name: Starting the Service
service:
name: "haproxy"
state: started
enabled: yes
handlers:
- name: "restart service"
service:
name: "haproxy"
state: restarted

Below is the ‘haproxy.j2’ file, in which our Httpd Servers will automatically be written in this.

#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main
bind *:2629
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
{% for webserver in groups["tag_Name_Ansible_WebServer"] %}
server app {{ webserver }}:80 check
{% endfor %}

→ I have also created a Video for this tutorial.

Outputs Section:

We can see the Changes in LoadBalancer VM:

Video URL for better explanation:

“I have practiced and gained all knowledge of this project(task) under the mentorship of Mr. VIMAL DAGA Sir during the Ansible Training in ARTH Program organized by Linux World India.”

I hope this article is Informative and Explanatory. Hope you like it, and give some claps !!!

For any suggestions or if any reader find any flaw in this article, please email me to “akhileshjain9221@gmail.com”

Thank You Readers!!!

--

--

Akhilesh Jain

I am a student and persuing under graduation in computer science and engineering.