How to Set Up an AWS Application Load Balancer for Two EC2 Servers
To put an Application Load Balancer (ALB) in front of two EC2 web servers, create a target group (type Instances, HTTP 80, health check path /) and register both instances, then create an internet-facing Application Load Balancer in at least two Availability Zones with a security group that allows HTTP 80 from anywhere and a listener on HTTP 80 that forwards to the target group. Allow port 80 on the instances only from the ALB's security group. When both targets show healthy, open the ALB's DNS name: requests are shared between the two servers.
Come on, friends! You have one server, and in a Diwali sale suddenly thousands of people arrive – then what? Or the server goes down? It is like our bike: we cannot say when it will stop – a server is the same. So we keep two servers and put a load balancer in front of them, which decides which server gets each request. Today we build Server 1 and Server 2 and split the traffic with an ALB.
चला मित्रांनो! एक सर्व्हर आहे आणि दिवाळी सेलला एकदम हजारो लोक आले तर? किंवा सर्व्हर बंद पडला तर? अभी अपना बाइक है, हम नहीं बता सकते बाइक कब बंद पड़ेगी – सर्व्हरचं पण तसंच आहे. म्हणून आपण दोन सर्व्हर्स ठेवतो आणि त्यांच्या पुढे एक लोड बॅलन्सर – जो प्रत्येक रिक्वेस्ट कोणत्या सर्व्हरला पाठवायची ते ठरवतो. आज Server 1 आणि Server 2 बनवून ALB ने ट्रॅफिक वाटूया.
चलो दोस्तों! एक सर्वर है और दिवाली सेल में अचानक हज़ारों लोग आ गए तो? या सर्वर बंद पड़ गया तो? अभी अपना बाइक है, हम नहीं बता सकते बाइक कब बंद पड़ेगी – सर्वर का भी वैसा ही है. इसलिए हम दो सर्वर्स रखते हैं और उनके आगे एक लोड बैलेंसर – जो तय करता है कि हर रिक्वेस्ट किस सर्वर को भेजनी है. आज Server 1 और Server 2 बनाकर ALB से ट्रैफ़िक बाँटेंगे.
Quick answer
The whole setup in short (console names):
1. Launch 2 × Amazon Linux 2023 with Nginx, in 2 different AZs (user data below)
2. Security groups: alb-sg = inbound HTTP 80 from 0.0.0.0/0
web-sg = inbound HTTP 80 from alb-sg, SSH 22 from My IP
3. EC2 → Target groups → Create → Instances, HTTP 80, health check "/" → register both
4. EC2 → Load balancers → Create → Application Load Balancer → Internet-facing,
2 AZs, alb-sg, Listener HTTP:80 → forward to the target group
5. Wait for "healthy", then: for i in 1 2 3 4 5 6; do curl -s http://<ALB-DNS-NAME>; done
What do I need before creating a load balancer?
- An AWS account with the default VPC (it has one public subnet in each Availability Zone).
- Basic EC2 skills: How to Launch an EC2 Instance in AWS and How to Install Nginx on Amazon Linux 2023.
- About 30 minutes. An ALB is not free: it is charged per hour plus usage, so delete it after the lab (Step 7).
How does an ALB share traffic between two servers?
Visitors send every request to the Application Load Balancer. The ALB checks the health of both targets and forwards requests to Server 1 and Server 2 in turn. If one server fails its health check, all traffic goes to the other.
व्हिजिटर्स प्रत्येक रिक्वेस्ट Application Load Balancer ला पाठवतात. ALB दोन्ही टार्गेट्सचा health चेक करतो आणि रिक्वेस्ट्स आळीपाळीने Server 1 आणि Server 2 कडे पाठवतो. एक सर्व्हर health check मध्ये फेल झाला तर सगळं ट्रॅफिक दुसऱ्या सर्व्हरकडे जातं.
विज़िटर्स हर रिक्वेस्ट Application Load Balancer को भेजते हैं. ALB दोनों टार्गेट्स का health चेक करता है और रिक्वेस्ट्स बारी-बारी से Server 1 और Server 2 को भेजता है. एक सर्वर health check में फ़ेल हुआ तो सारा ट्रैफ़िक दूसरे सर्वर पर जाता है.
The visitor never talks to the servers directly. The ALB receives every request, sends it to a healthy target (round robin by default), and returns the answer. A health check asks each server for / every few seconds; a server that stops answering gets no traffic until it recovers.
How do I set up an Application Load Balancer for two EC2 servers?
Step 1 — Create the two security groups
EC2 → Security Groups → Create security group:
| Name | Inbound rule | Source | Why |
|---|---|---|---|
alb-sg |
HTTP, TCP 80 | Anywhere-IPv4 0.0.0.0/0 |
Visitors reach the load balancer |
web-sg |
HTTP, TCP 80 | Custom → alb-sg (the security group) |
Only the ALB may reach the servers |
web-sg |
SSH, TCP 22 | My IP | Only you can log in |
Create alb-sg first, so you can choose it as the source in web-sg.
Step 2 — Launch two web servers in two Availability Zones
Launch an Amazon Linux 2023 instance with web-sg, and in Network settings → Edit choose a subnet in, for example, ap-south-1a. Under Advanced details → User data paste:
#!/bin/bash
yum install -y nginx
echo "<h1>Server 1 – $(hostname -f)</h1>" > /usr/share/nginx/html/index.html
service nginx start
systemctl enable nginx
Launch the second instance the same way in another zone (for example ap-south-1b) and change Server 1 to Server 2. User data runs once as root at the first boot, so no sudo is needed there.
Step 3 — Check each server on its own
SSH into each instance and confirm Nginx answers locally:
curl -s http://localhost # <h1>Server 1 – ip-172-31-...</h1>
sudo service nginx status
Because web-sg only allows port 80 from the ALB, the public IP of a server will not open in your browser. That is correct and secure.
Ravindra Bagale's Tip
Many students leave the web servers' security group open to 0.0.0.0/0 on port 80 – then people can bypass the ALB and hit a server directly. In web-sg choose alb-sg as the source, not an IP. The security group is a wall of fire: open just one gate for the ALB and keep everything else closed. Keep this in mind!
Ravindra Bagale's Tip – मराठी
खूप स्टुडंट्स वेब सर्व्हर्सचा सिक्युरिटी ग्रुप पोर्ट 80 साठी 0.0.0.0/0 ला उघडा ठेवतात – मग लोक ALB ला बायपास करून डायरेक्ट सर्व्हरला हिट करू शकतात. web-sg मध्ये सोर्स म्हणून alb-sg निवडा, IP नाही. सिक्युरिटी ग्रुप म्हणजे आग लागलेली भिंत: ALB साठी एकच गेट उघडा, बाकी सगळे बंद. ध्यान रखो!
Ravindra Bagale's Tip – हिंदी
बहुत स्टूडेंट्स वेब सर्वर्स का सिक्योरिटी ग्रुप पोर्ट 80 के लिए 0.0.0.0/0 पर खुला छोड़ देते हैं – फिर लोग ALB को बायपास करके सीधे सर्वर को हिट कर सकते हैं. web-sg में सोर्स के तौर पर alb-sg चुनो, IP नहीं. सिक्योरिटी ग्रुप मतलब आग लगी दीवार: ALB के लिए एक ही गेट खोलो, बाक़ी सब बंद. ध्यान रखो!
Step 4 — Create the target group
EC2 → Target groups → Create target group → target type Instances → name web-tg → protocol HTTP, port 80 → your VPC → health check protocol HTTP, path / → Next. Tick both instances → Include as pending below → Create target group.
Step 5 — Create the Application Load Balancer
EC2 → Load balancers → Create load balancer → Application Load Balancer → Create:
| Setting | Value |
|---|---|
| Name | web-alb |
| Scheme | Internet-facing, IP address type IPv4 |
| Network mapping | Your VPC, tick at least two Availability Zones (the ones where your servers run) |
| Security groups | Remove default, choose alb-sg |
| Listeners and routing | HTTP : 80 → Forward to web-tg |
Click Create load balancer. The state goes from Provisioning to Active in a few minutes.
Step 6 — Test that traffic is split
Target groups → web-tg → Targets: wait until both show healthy. Copy the ALB DNS name (for example web-alb-1234567890.ap-south-1.elb.amazonaws.com) and run from your laptop:
for i in 1 2 3 4 5 6; do curl -s http://web-alb-1234567890.ap-south-1.elb.amazonaws.com; echo; done
You see Server 1 and Server 2 taking turns. Now stop Nginx on one server (sudo service nginx stop): after a few failed health checks that target becomes unhealthy and every request goes to the other server — the site stays up. ⚖️ Start Nginx again and it comes back.
For your own domain, point a CNAME (for example www) to the ALB DNS name. Do not use the ALB's IP addresses; they change.
Ravindra Bagale's Tip
When the targets show unhealthy, don't delete the ALB straight away. Pay attention, the order is: first on the server, curl -I http://localhost/ – do you get 200? Then, does web-sg allow port 80 from alb-sg? Then the target group's health check path. Very often nobody verified whether Nginx had even started. Check one thing at a time.
Ravindra Bagale's Tip – मराठी
Targets unhealthy दिसतात तेव्हा लगेच ALB डिलीट करू नका. लक्ष द्या, क्रम असा: आधी सर्व्हर वर curl -I http://localhost/ – 200 येतो का? मग web-sg मध्ये पोर्ट 80 चा सोर्स alb-sg आहे का? मग target group चा health check path. खूप वेळा Nginx स्टार्ट हुआ है या नहीं व्हेरिफाय केलंच नसतं. एक एक चेक करा.
Ravindra Bagale's Tip – हिंदी
Targets unhealthy दिखें तो तुरंत ALB डिलीट मत करो. ध्यान दो, क्रम ऐसा है: पहले सर्वर पर curl -I http://localhost/ – 200 आता है क्या? फिर web-sg में पोर्ट 80 का सोर्स alb-sg है क्या? फिर target group का health check path. बहुत बार Nginx स्टार्ट हुआ है या नहीं, यही वेरिफाय नहीं किया होता. एक एक चीज़ चेक करो.
Step 7 — Clean up after the lab
Delete in this order: the load balancer, then the target group, then terminate both instances, and finally the two security groups. The ALB keeps charging every hour until it is deleted.
How do I fix common load balancer problems?
Ghabru naka 😅 — these are the usual ones:
| Symptom | Likely cause | Fix |
|---|---|---|
Targets unhealthy (Health checks failed) |
web-sg does not allow 80 from alb-sg; Nginx stopped |
Fix the rule; sudo service nginx start; curl -I http://localhost/ |
| Targets unhealthy with code 404 or 403 | Health check path does not exist on the server | Use / or a path that returns 200 |
| 502 Bad Gateway | Target closed the connection or the web server crashed | Check Nginx on the targets and /var/log/nginx/error.log |
| 503 Service Temporarily Unavailable | No healthy targets registered | Register both instances; fix the health check |
| ALB DNS name times out | alb-sg missing HTTP 80, or an internal scheme was chosen |
Allow 80 from 0.0.0.0/0 in alb-sg; the scheme must be internet-facing |
| Always the same server | Browser cache, or stickiness is on | Use curl in a loop; turn off stickiness in target group attributes |
Learn it properly
This guide is the short path. These free lessons explain the building blocks:
Samajla ka? Got it? Two servers, a target group, a health check, alb-sg and web-sg, and the ALB – now the site stays up even if one server goes down. Don't forget to delete the ALB after the lab. You will get it, slowly you will get it.
समजलं का? दोन सर्व्हर्स, target group, health check, alb-sg आणि web-sg, आणि ALB – आता एक सर्व्हर बंद पडला तरी साइट चालू राहते. लॅब झाली की ALB डिलीट करायला विसरू नका. कळेल तुम्हाला, हळू हळू कळेल.
समझ आया? दो सर्वर्स, target group, health check, alb-sg और web-sg, और ALB – अब एक सर्वर बंद पड़ जाए तब भी साइट चालू रहती है. लैब के बाद ALB डिलीट करना मत भूलना. धीरे धीरे समझ में आएगा.
Frequently asked questions
How does an Application Load Balancer split traffic?
The ALB forwards each request to a healthy target in the target group, using round robin by default. Unhealthy targets get no traffic until they pass the health check again.
Why are my ALB targets unhealthy?
The instance security group does not allow port 80 from the ALB security group, Nginx is not running, or the health check path does not return 200. Test with curl -I http://localhost/ on each server.
Why does the ALB need two Availability Zones?
An Application Load Balancer must be placed in at least two subnets in different Availability Zones, so it keeps working if one zone has a problem.
Should my EC2 servers be open to the internet behind an ALB?
No. Allow HTTP on the instances only from the ALB security group. Visitors reach the servers through the ALB, and SSH stays on My IP.
Why do I always see the same server when I refresh?
The browser may reuse a cached page. Use a private window or run curl a few times. Also check that stickiness is off in the target group attributes.
Does an Application Load Balancer cost money?
Yes. It is charged per hour plus usage, even with little traffic. Delete the load balancer and the target group after the lab.