Configure HAProxy Loadblancer With Dynamic Inventory using Ansible on AWS

Nischal Vooda
5 min readOct 29, 2020

--

Problem Statement

Statement: Deploy a Load Balancer and multiple Web Servers on AWS instances through ANSIBLE!

  • Provision EC2 instances through ansible.
  • Retrieve the IP Address of instances using the dynamic inventory concept.
  • Configure the web servers through the ansible role.
  • Configure the load balancer through the ansible role.
  • The target nodes of the load balancer should auto-update as per the status of web servers.

About Ansible

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems and can configure both Unix-like systems as well as Microsoft Windows. It includes its own declarative language to describe system configuration. Ansible was written by Michael DeHaan and acquired by Red Hat in 2015. Ansible is agentless, temporarily connecting remotely via SSH or Windows Remote Management (allowing remote PowerShell execution) to do its tasks.

About HaProxy LoadBalancer

HAProxy is free, open-source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers. It is written in C and has a reputation for being fast and efficient (in terms of processor and memory usage).

About EC2 Instance

Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides secure, resizable compute capacity in the cloud. It is designed to make web-scale cloud computing easier for developers. Amazon EC2’s simple web service interface allows you to obtain and configure capacity with minimal friction.

To install ansible make sure that you have installed python in your Virtual Machine just by using the following command

python3 -V

After the confirmation just run the following command

pip3 install ansible

Dependencies

On your machine, have the following installed.

  • Ansible
  • Python ≥ 2.6, with boto, boto3, and botocore.

Install boto and boto3 libraries..

pip3 install boto
pip3 install boto3

Write the ansible code to launch 4 EC2 instances namely web1, web2, web3, and LB… Here is the code ~

- hosts: localhost
vars_files:
— credentials.yml
— variables.yml
vars:
vmtags:
— "website1"
— "website2"
— "website3"
— "load balancer"
tasks:
— name: Launching four instances on AWS Cloud
ec2:
key_name: "{{ aws_key_pair }}"
instance_type: "{{ aws_instance_type }}"
image: "{{ aws_image }}"
wait: yes
vpc_subnet_id: "{{ aws_subnet_id }}"
assign_public_ip: yes
region: "{{ aws_region }}"
state: present
group: "{{ aws_SG }}"
aws_access_key: "{{ awsuser }}"
aws_secret_key: "{{ awspass }}"
instance_tags:
Name: "{{ item }}"
loop: "{{ vmtags }}"

👉 In the vars_file section, I have given two files for AWS credentials and the key pair, subnet ids, and security group, etc,…
👉 AWS Credentials are critical for us, So use ansible-vault to secure your credentials … Run the below and then give your credentials …

ansible-vault create — vault-id prod@prompt credentials.yml

👉 Here is the variables.yml file

- aws_key_pair: "hcc81"
- aws_instance_type: "t2.micro"
- aws_image: "ami-052c08d70def0ac62"
- aws_subnet_id: "subnet-1f3c4953"
- aws_region: "ap-south-1"
- aws_SG: "default"

Now run the ansible-playbook to launch 4 EC2 instances on AWS CLoud …

ansible-playbook --vault-id prod@prompt <filename.yml>

You can check in AWS Console also

We have to retrieve the EC2 instances IPs using dynamic inventory to configure haproxy in one instance and httpd web server in the remaining three web servers

# yum install wget -y# wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/ec2.py# wget https://raw.githubusercontent.com/ansible/ansible/stable-2.9/contrib/inventory/ec2.ini//make both files executable# chmod +x ec2.py
# chmod +x ec2.ini// Export your AWS credentials and AWS Region ...# export AWS_REGION='ap-south-1'
# export AWS_ACCESS_KEY_ID='XXXXXXXXXXXXXXX'
# export AWS_SECRET_ACCESS_KEY='XXXXXXXXXXXXXXXX'

Now run the ec2.py file as shown below.

# ./ec2.py

You can see all the EC2 IP’s of running instances … Now manually type the IP’s in the new txt file …

Now ping those EC2 IP’s whether they are pinging or not !!! . Before pinging do some changes in ansible.cfg file … Here are the settings ~

[defaults]
inventory = /myinventory/ec2ip.txt
host_key_checking = False
remote_user = ec2-user
ask_pass = False
private_key_file=/root/hcc81.pem
roles_path=/path/to/roles[privilege_escalation]
become = True
become_user = root
become_ask_pass = false
become_method = sudo

Now create two roles for configuring web servers in three instances namely web1, wb2, wb3, and haproxy in LB instance

# ansible-galaxy init loadbalancer
# ansible-galaxy init webserver
# ansible-galaxy list

In load balancer role ~
Now write the code to install haproxy and edit the config file in the controller node…

//write the below code in loadbalancer/tasks/main.yml
---
# tasks file for loadbalancer- name: Install HAPROXY package
package:
name: "haproxy"
state: present- name: Copy haproxy conf to target IP
template:
src: "haproxy.cfg"
dest: "/etc/haproxy/haproxy.cfg"
notify: restart haproxy- name: Start HAPROXY Service
service:
name: "haproxy"
state: started//write the below code in loadbalancer/handlers/main.yml
---
# handlers file for loadbalancer- name: restart haproxy
service:
name: "haproxy"
state: restarted

Copy the haproxy.cfg to loadbalancer/templates/haproxy.cfg… And do some changes to dynamically retrieve the IP’s of webservers …

In webserver role ~
Install httpd server and copy the index.html to controller node … Here is the code …

// write below code in webserver/tasks/main.yml
---
# tasks file for webserver- name: Install HTTPD package
package:
name: "httpd"
state: present- name: copy required webpages to target IP’s
copy:
content: "hello i am nischal Host Server : {{ ansible_hostname }}"
dest: /var/www/html/index.html- name: Start the service
service:
name: "httpd"
state: started

That’s it… Created two roles to configure a load balancer and webservers for balancing the load of all three webservers …

Create another playbook to run two roles one by one …

- hosts: loadbalancer
roles:
— loadbalancer- hosts: webservers
roles:
— webserver// run the above playbook ...# ansible-playbook deploy.yml

After successful configuration, we can see that webpages are running on the webserver.

Output:

Now type the LB instance public IP to see the output …

Connect me on my LinkedIn as well.

--

--

No responses yet