Configuring HAProxy on EC2 Instance and auto updating its conf. file with Ansible

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 :

No alt text provided for this image

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 :

No alt text provided for this image

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 :

No alt text provided for this image

My Server is running with private IP : 172.31.35.119 So, the above web page shows this IP.

Thank You😀

To view or add a comment, sign in

More articles by Sri Krishna Sagar Akurathi

Others also viewed

Explore content categories