Ansible Playbook to Configure HAProxy and HTTP Web Server on EC2 Instances and Dynamically updating IPs in HAProxy Configuration file

Karan Agrawal
4 min readJan 17, 2021

In this article we will:

  1. Launch 3 Instances on AWS
  2. Configure 2 of them as Apache Web Servers
  3. Configure 1 of them HAProxy Load Balancer

Setting Up Ansible Controller Node

  1. Launch Instance
  2. Install Ansible using the command:
pip3 install ansible

3. Transfer key to Controller Node (.pem file)

4. Set up the configuration file (/etc/ansible/ansible.cfg)

5. Set up inventory file.

That’s all Ansible Controller Node is all set.

Setting Up Apache Server and HAProxy using Ansible Playbook

Run the following playbook to Set up Apache and HAProxy.

- hosts: ws
tasks:
- name: "Installing HTTPD and PHP"
package:
name:
- "httpd"
- "php"
state: present
- name: "Writing Webpages"
copy:
dest: "/var/www/html/index.php"
content: "<pre>\n<h1>Task 12</h1>\n<h2>Done By Karan Agrawal</h2>\n <?php\n\nprint `/usr/sbin/ifconfig`\n\n?>\n</pre>"
- name: "Starting Services"
service:
name: "httpd"
state: restarted
- hosts: lb
vars:
port: "8080"
tasks:
- name: "Installing HAProxy"
package:
name: "haproxy"
state: present
- name: "Configuring HAProxy"
template:
dest: "/etc/haproxy/haproxy.cfg"
src: "/haproxy.cfg.j2"
- name: "Starting HAProxy service on IP {{ ansible_facts['default_ipv4']['address'] }}:{{ port }}"
service:
name: "haproxy"
state: restarted

Use this file as haproxy.cfg.j2

#---------------------------------------------------------------------
# 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 *:{{ 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['ws'] %}
server app{{ loop.index }} {{ i }}:80 check
{% endfor %}

From this file, IP’s will be added dynamically in the configuration file.

Run the Playbook.

We can see IPs are automatically added in the configuration file.

Our Load Balancer and Web Servers are working perfectly.

For Github Link, click here.

--

--