Configuring HAProxy on EC2 Instance and auto updating its conf. file with Ansible
ARTH Task 12.2
In my previous article, I've shown how to configure HAProxy software on top of a target node with Ansible and how to update the HAProxy conf. file dynamically when a new server adds to the inventory of ansible!
GitHub URL for this entire Task :
For this Task, I've launched Two new RedHat AWS EC2 Instances :
The Two EC2 Instances public IP's are copied to the inventory file as below : The first IP works as a Load Balancer Instance and the Second IP under "Servers" host group works as a backend server :
[LB]
65.0.132.133
[Servers]
13.234.77.216
The Configuration file of ansible (/etc/ansible/ansible.cfg) should look like this :
[defaults] inventory = /root/inventory.txt host_key_checking = false command_warnings = false deprecation_warnings = false remote_user = ec2-user ask_pass = false private_key_file = /root/task12_2/aws_latest_key.pem [privilege_escalation] become = true become_method = sudo become_user = root
become_ask_pass = false
In your conf. file, remember to change the inventory file location, private_key_file path(The key file which will be used to login to the EC2 Instance by Ansible). The privilege_escalation is cumpolsory because we need to install some software which requires admin or root power
Before running the playbook, you must keep the haproxy.cfg template file and index.php(Web page) in the same directory as the main ansible playbook which will be used to copy them inside the EC2 Instances.
The following is the haproxy.cfg file. It uses the LB_port variable to set the port of load balancer. It also uses the IP's under the group name "Servers" to set them as Backend Servers through loop using jinja :
#---------------------------------------------------------------------
# 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 *:{{ LB_port }}
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 i in groups['Servers'] %}
server app{{ loop.index }} {{ i }}:80 check
{% endfor %}
The index.php file has the following code which outputs the ifconfig command on the Instance it is running which helps us to know from which Instance we are getting output :
<pre> <?php print `/usr/sbin/ifconfig` ?>
</pre>
Let's Get to the Main-one, Playbook
Configuring Servers :
The following code is used to install the httpd software in servers :
- name: "Installing httpd software"
package:
name: httpd
state: present
The following code is used to install the php software in servers :
- name: "Installing php software"
package:
name: php
state: present
The following code is for starting and enabling the httpd service :
- name: "Starting and Enabling httpd service"
service:
name: httpd
state: started
enabled: yes
The following is the code for copying the index.php file to the Document root of Instance:
- name: "Copying the index.php file"
copy:
src: index.php
dest: /var/www/html/index.php
Now, The servers are Configured!
Let's Configure the Load Balancer :
The following code is for taking input from user for the port number on top of which haproxy runs :
vars_prompt:
- name: LB_port
private: no
prompt: "Enter the port for Load Balancer"
Tasks:
The following code is for installing HAProxy software in the load balancer Instance :
- name: "Installing HAProxy"
package:
name: haproxy
state: present
The SELinux don't permit the HAProxy to restart. So, we need to temporarily stop it :
- name: "Setting SELinux to Permissive Temporarily"
selinux:
state: permissive
policy: targeted
The following is the code for starting and enabling the HAProxy Service :
- name: "Starting and Enabling HAProxy Service"
service:
name: haproxy
state: started
enabled: yes
The following code copies the haproxy.cfg template file to the Instance inside the location : /var/haproxy/haproxy.cfg. It uses handler to restart the haproxy service whenever there is any change in the conf. file :
- name: "Updating HAProxy Conf. file"
template:
src: haproxy.cfg
dest: /etc/haproxy/haproxy.cfg
notify:
- restart_haproxy
The below is the handler used to restart haproxy :
handlers:
- name: "restart_haproxy"
service:
name: haproxy
state: restarted
The below code is the entire playbook :
- hosts: Servers tasks: - name: "Installing httpd software" package: name: httpd state: present - name: "Installing php software" package: name: php state: present - name: "Starting and Enabling httpd service" service: name: httpd state: started enabled: yes - name: "Copying the index.php file" copy: src: index.php dest: /var/www/html/index.php - hosts: LB vars_prompt: - name: LB_port private: no prompt: "Enter the port for Load Balancer" tasks: - name: "Installing HAProxy" package: name: haproxy state: present - name: "Setting SELinux to Permissive Temporarily" selinux: state: permissive policy: targeted - name: "Starting and Enabling HAProxy Service" service: name: haproxy state: started enabled: yes - name: "Updating HAProxy Conf. file" template: src: haproxy.cfg dest: /etc/haproxy/haproxy.cfg notify: - restart_haproxy handlers: - name: "restart_haproxy" service: name: haproxy
state: restarted
Let's run the Playbook :
I've given the Load Balancer Port as "5000".
Now, Head on to the browser and type : "https://PublicIPofLoadBalancer:5000". You will see the ifconfig command output :
My Server is running with private IP : 172.31.35.119 So, the above web page shows this IP.