Building and Verifying an ALB Setup


This guide documents the entire process of setting up a highly available web application using AWS, from creating the VPC and subnets to configuring the Application Load Balancer (ALB) and testing its functionality. Let’s break it down step by step.
📌Step 1: Setting Up the VPC and Subnets
Objective: Create a VPC to host all resources in a private network.
Create a VPC:
Go to AWS Management Console > VPC > Create VPC.
Name:
ha-vpc
.IPv4 CIDR:
10.0.0.0/16
.IPv6 CIDR: (Optional, leave blank for now).
Tenancy: Default.
Create VPC.
Create Subnets:
Go to Subnets > Create Subnet.
Subnet 1 (
ha-subnet-1
):VPC:
ha-vpc
.Availability Zone:
us-east-1a
.CIDR:
10.0.1.0/24
.Enable auto-assign public IP.
Subnet 2 (
ha-subnet-2
):VPC:
ha-vpc
.Availability Zone:
us-east-1b
.CIDR:
10.0.2.0/24
.Enable auto-assign public IP.
Create both subnets.
Create Internet Gateway:
Go to Internet Gateways > Create Internet Gateway.
Name:
ha-igw
.Attach to
ha-vpc
.
Update Route Tables:
Go to Route Tables > Select the main route table for
ha-vpc
.Add route: Destination
0.0.0.0/0
, Targetha-igw
.Associate with
ha-subnet-1
andha-subnet-2
.
📌Step 2: Setting Up Security Groups
Objective: Define network access rules.
Create
alb-sg
:Go to Security Groups > Create Security Group.
Name:
alb-sg
.VPC:
ha-vpc
.Inbound Rules:
- Type: HTTP, Port: 80, Source:
0.0.0.0/0
.
- Type: HTTP, Port: 80, Source:
Outbound Rules:
- Type: HTTP, Port: 80, Destination: Custom (to be updated later).
Create
nginx-sg
:Name:
nginx-sg
.VPC:
ha-vpc
.Inbound Rules:
Type: HTTP, Port: 80, Source:
alb-sg
.Type: SSH, Port: 22, Source: Your IP.
Outbound Rules:
- Type: All Traffic, Destination:
0.0.0.0/0
.
- Type: All Traffic, Destination:
Create
webapp-sg
:Name:
webapp-sg
.VPC:
ha-vpc
.Inbound Rules:
Type: SSH, Port: 22, Source: Your IP.
Type: Custom TCP, Port: 3000, Source:
nginx-sg
(updated later).
Outbound Rules:
- Type: All Traffic, Destination:
0.0.0.0/0
.
- Type: All Traffic, Destination:
📌Step 3: Launching EC2 Instances
Objective: Set up webapp and NGINX instances.
Launch
webapp-ec2-1
:Go to EC2 > Launch Instance.
AMI: Amazon Linux 2.
Instance Type: t2.micro.
Subnet:
ha-subnet-1
.Security Group:
webapp-sg
.Key Pair: Upload or create
your-key.pem
.Install Node.js:
sudo yum update -y sudo yum install -y nodejs
Create app:
mkdir ~/app cd ~/app echo "const http = require('http'); http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('<h1>Welcome to Webapp EC2-1</h1>'); }).listen(3000);" > server.js node server.js &
Launch
webapp-ec2-2
:Similar to
webapp-ec2-1
, inha-subnet-2
.Update
server.js
to:<h1>Welcome to Webapp EC2-2</h1>
.
Launch
nginx-ec2-1
:Subnet:
ha-subnet-1
.Security Group:
nginx-sg
.Install NGINX:
sudo amazon-linux-extras install nginx1.12 -y sudo systemctl start nginx sudo systemctl enable nginx
Configure NGINX:
sudo nano /etc/nginx/nginx.conf
Content:
http { server { listen 80; server_name nginx-ec2-1; location / { proxy_pass http://<webapp-ec2-1-private-ip>:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; add_header X-Served-By "nginx-ec2-1"; #optional, dont use if you are seeing any error } location /health { return 200 'OK'; add_header Content-Type text/plain; add_header X-Served-By "nginx-ec2-1";#optional, dont use if you are seeing any error } } }
Reload:
sudo nginx -t && sudo systemctl reload nginx
.
Launch
nginx-ec2-2
:Similar to
nginx-ec2-1
, inha-subnet-2
.Update
proxy_pass
to<webapp-ec2-2-private-ip>:3000
andX-Served-By
tonginx-ec2-2
.
📌Step 4: Configuring the ALB
Objective: Set up load balancing.
Create Target Group (
nginx-target-group
):Go to EC2 > Target Groups > Create Target Group.
Type: IP.
Protocol: HTTP, Port: 80.
Health Check: Path
/health
, Success Codes:200
.Register Targets: Add
nginx-ec2-1
andnginx-ec2-2
private IPs.
Create ALB (
ha-alb
):Go to EC2 > Load Balancers > Create Load Balancer.
Type: Application Load Balancer.
Name:
ha-alb
.Scheme: Internet-facing.
Subnets:
ha-subnet-1
,ha-subnet-2
.Security Group:
alb-sg
.Listener: HTTP:80, Forward to
nginx-target-group
.
Update Security Groups:
alb-sg
Outbound: HTTP, Port 80, Destination:nginx-sg
.nginx-sg
Inbound: HTTP, Port 80, Source:alb-sg
.
📌Step 5: Initial Troubleshooting
Date/Time: July 15, 2025, ~12:00 PM IST
Problem: Couldn’t identify which EC2 was serving, and curl http://<alb-dns-name>
failed.
Added Headers: Modified NGINX configs for
X-Served-By
.Fixed
webapp-ec2-2
: Adjustedwebapp-sg
to allow port 3000.Checked ALB: Ensured listeners and health checks worked.
📌Step 6: Verifying ALB Functionality
Problem: Wanted to confirm ALB perfection.
Tested Load: Used
for
loop to check distribution.Tested Failover: Stopped instances and verified traffic shift.
Fixed Syntax: Adjusted loop with
seq
when needed.
📌Step 7: Resolving Port 3000 Issue
Problem: curl
http://localhost:3000
failed on NGINX.
Diagnosed: Confirmed NGINX proxies on port 80, not 3000.
Verified Proxy: Tested connectivity to
webapp-ec2-2:3000
.Secured SG: Restricted
webapp-sg
tonginx-sg
.
📌Step 8: Manual Load Testing
Problem: Wanted to manually check load after stopping instances.
Baseline Test: Ran loop to see distribution.
Stopped
webapp-ec2-1
: Shifted load tonginx-ec2-2
.Stopped
nginx-ec2-1
: Confirmed full traffic tonginx-ec2-2
.Restarted: Restored balance.
—> If you have any error while implimenting a load balancer ask me in comments!! Happy to help :)
Subscribe to my newsletter
Read articles from Poonam Vetal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Poonam Vetal
Poonam Vetal
I am student from Pune institute of computer technology !🎓