This repository documents a hands-on implementation of an HAProxy-based Load Balancer deployed on AWS EC2, designed to distribute HTTP traffic across multiple backend web servers using a round-robin algorithm.
The lab was treated like a real production environment, covering infrastructure provisioning, service configuration, failure analysis, root cause identification, and validation after resolution.
- Cloud Provider: AWS
- OS: Ubuntu 24.04 LTS
- Instances:
- 1 × HAProxy Load Balancer
- 2 × Nginx Backend Servers
- Availability Zone: ap-south-1a
- Load Balancing Algorithm: Round Robin
The following diagram represents the logical flow of traffic in the setup.
Traffic Flow:
Users → Internet Gateway → HAProxy (Public Subnet) → Nginx Backends (Public Subnets)
During initial setup, SSH access to all EC2 instances failed, including:
- HAProxy server
- Nginx backend servers
This immediately suggested an infrastructure-level failure, not an OS or service issue.
- The VPC had no Internet Gateway (IGW) attached
- The Route Table was missing a default route (
0.0.0.0/0)
Without these:
- Instances could not reach the internet
- SSH access was impossible
- Package installation and updates were blocked
The issue was fixed manually via the AWS Console:
- Attached an Internet Gateway to the VPC
- Updated the Route Table with:
0.0.0.0/0 → Internet Gateway
- Ensured the public subnet was associated with the corrected route table
Once applied, SSH access was immediately restored.
This incident reinforced the importance of validating cloud networking components before debugging operating systems or applications.
Each backend server was configured with a unique response to clearly verify traffic distribution:
- Server 1:
Welcome to Server 1! - Server 2:
Welcome to Server 2!
HAProxy listens on port 80 and forwards traffic to backend servers using round-robin load balancing.
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
server server1 172.31.100.254:80
server server2 172.31.100.5:80After deployment, accessing the HAProxy public IP returned backend responses successfully.
Initially, only Server 2 appeared to respond. After reviewing the HAProxy configuration and backend status, the issue was identified as browser caching, not load balancing.
Fix: Performed a hard refresh:
Ctrl + Shift + R
After this, responses alternated correctly between both backend servers.
You may notice that EC2 public IP addresses differ between the start and end of the lab.
- EC2 instances were manually stopped and restarted
- AWS assigns dynamic public IPs by default
- When an instance stops, its public IP is released
- On restart, a new public IP is assigned
✅ This behavior is expected unless an Elastic IP (EIP) is used.
HAProxy is a high-performance load balancer that sits between clients and backend services, distributing incoming traffic intelligently. By using algorithms like round robin, it ensures that no single backend server becomes overwhelmed. Load balancing is critical for high availability, allowing applications to remain accessible even when individual components fail. It also enables horizontal scalability by making it easy to add or remove backend servers. Most importantly, load balancers eliminate single points of failure, which is a foundational principle of resilient system design.
This lab reflects common real-world cloud challenges, including:
- VPC and routing misconfigurations
- Infrastructure-level access issues
- Client-side caching effects
- Cloud resource lifecycle behavior”*
It demonstrates not just how to configure HAProxy, but how to think and operate like an SRE.
-
Cloud networking is foundational to all compute services
Even when instances are running and security groups appear correct, missing VPC components such as an Internet Gateway or proper route table entries can completely block access. Validating network architecture early prevents unnecessary debugging at the OS or application layer.
-
Shared infrastructure failures affect all resources equally
The inability to SSH into multiple EC2 instances at the same time indicated a common dependency issue rather than isolated host misconfiguration. This reinforced the importance of analyzing failures at the correct abstraction level.
-
Client-side behavior can influence perceived application results
The load balancer initially appeared to route traffic to only one backend server. The issue was ultimately caused by browser caching, demonstrating that verification should include both server-side and client-side checks.
-
Load-balancing behavior depends heavily on configuration choices
Using round-robin without health checks works for basic traffic distribution, but it also highlights why health checks are critical in real-world deployments to ensure traffic is not sent to unavailable backends.
-
EC2 public IP addresses are ephemeral by default
Restarting EC2 instances resulted in changed public IPs, which is expected behavior unless Elastic IPs are used. This emphasizes the importance of designing access mechanisms that account for infrastructure lifecycle events.
-
Clear documentation improves operational clarity
Recording configuration steps, issues encountered, and resolution details makes the setup easier to understand, reproduce, and troubleshoot in future deployments.
This project was completed as part of a technical workshop focused on cloud infrastructure and traffic engineering.
- Assignment Provided by: Sam Osung
- Learning Objective: The core focus was on hands-on VPC networking, HAProxy configuration, and systematic Root Cause Analysis (RCA) in a cloud-native environment.






