Real-Time Elastic Scaling with ALB & Auto Scaling
Deploy a dynamic, self-healing, and elastic web tier on AWS. In this production lab, we configure an Application Load Balancer (ALB), an isolated Target Group, and an Auto Scaling Group (ASG) using Ubuntu 24.04/22.04 LTS instances running automated IMDSv2 metadata ingestion.
0 Required Prerequisites & Architecture Components
Verify that your AWS environment satisfies the architectural baseline before provisioning.
Multi-AZ VPC
2+ Public Subnets
Ubuntu LTS
24.04 or 22.04 AMI
IMDSv2
Session Tokens
Auto Scaling
Capacity 1 to 4
1 Security Architecture & Group Isolation
Follow the principle of defense-in-depth: the Load Balancer is exposed to public HTTP traffic, but the Auto Scaling backend instances accept requests exclusively from the ALB security group.
| Security Group | Port | Source | Purpose |
|---|---|---|---|
| alb-sg | 80 (HTTP) | 0.0.0.0/0 | Accept public incoming client traffic |
| ec2-instance-sg | 80 (HTTP) | alb-sg (Group ID) | Strict ingress restriction to ALB forwarding only |
Architecture Tip
Never open port 80 directly to 0.0.0.0/0 on backend
EC2 instances. Restricting the source to
alb-sg prevents clients from bypassing load
balancing and security policies.
2 Provisioning the Target Group (TG)
The Target Group routes requests to the pool of healthy EC2 instances dynamically managed by Auto Scaling.
- Navigate to EC2 Console > Target Groups > Create target group.
-
Set Target type to
Instances. -
Name the group:
ubuntu-web-tg. -
Set Protocol to
HTTPand Port to80. -
Set Health check path to
/with ProtocolHTTP. - Click Next and do not manually register targets—the Auto Scaling Group will attach and detach targets dynamically.
3 Configuring the Application Load Balancer (ALB)
Provision the internet-facing entry point across multiple Availability Zones for high availability.
- Navigate to EC2 Console > Load Balancers > Create load balancer.
- Select Application Load Balancer (ALB).
-
Name:
ubuntu-demo-alb. - Scheme: Internet-facing | IP address type: IPv4.
- Network Mapping: Select your VPC and check at least 2 Availability Zones and their public subnets.
-
Security Groups: Select
alb-sg(remove the default group). -
Listeners and Routing: Listener HTTP:80 forward
to
ubuntu-web-tg. - Click Create load balancer.
4 Launch Template & Converted Ubuntu User Data
Create the template blueprint used by Auto Scaling. It includes the converted Ubuntu bootstrap script that retrieves runtime metadata (Instance ID, Type, AZ) via IMDSv2 and renders the status dashboard[cite: 1].
Launch Template Configuration:
-
• Template Name:
ubuntu-web-lt - • AMI: Ubuntu Server 24.04 LTS or 22.04 LTS (HVM, SSD Volume Type)
-
• Instance Type:
t2.microort3.micro -
• Security Group:
ec2-instance-sg - • Advanced Details > Metadata Version: V2 only (token required)
#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y apache2 git curl
export TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
export META_INST_ID=`curl http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN"`
export META_INST_TYPE=`curl http://169.254.169.254/latest/meta-data/instance-type -H "X-aws-ec2-metadata-token: $TOKEN"`
export META_INST_AZ=`curl http://169.254.169.254/latest/meta-data/placement/availability-zone -H "X-aws-ec2-metadata-token: $TOKEN"`
cd /var/www/html
echo "<!DOCTYPE html>" > index.html
echo "<html lang=\"en\">" >> index.html
echo "<head>" >> index.html
echo " <meta charset=\"UTF-8\">" >> index.html
echo " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" >> index.html
echo " <style>" >> index.html
echo " @import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');" >> index.html
echo " html {" >> index.html
echo " position: relative;" >> index.html
echo " overflow-x: hidden !important;" >> index.html
echo " }" >> index.html
echo " * {" >> index.html
echo " box-sizing: border-box;" >> index.html
echo " }" >> index.html
echo " body {" >> index.html
echo " font-family: 'Open Sans', sans-serif;" >> index.html
echo " color: #324e63;" >> index.html
echo " }" >> index.html
echo " .wrapper {" >> index.html
echo " width: 100%;" >> index.html
echo " height: auto;" >> index.html
echo " min-height: 90vh;" >> index.html
echo " padding: 50px 20px;" >> index.html
echo " padding-top: 100px;" >> index.html
echo " display: flex;" >> index.html
echo " }" >> index.html
echo " .instance-card {" >> index.html
echo " width: 100%;" >> index.html
echo " min-height: 380px;" >> index.html
echo " margin: auto;" >> index.html
echo " box-shadow: 12px 12px 2px 1px rgba(13, 28, 39, 0.4);" >> index.html
echo " background: #fff;" >> index.html
echo " border-radius: 15px;" >> index.html
echo " border-width: 1px;" >> index.html
echo " max-width: 500px;" >> index.html
echo " position: relative;" >> index.html
echo " border: thin groove #9c83ff;" >> index.html
echo " }" >> index.html
echo " .instance-card__cnt {" >> index.html
echo " margin-top: 35px;" >> index.html
echo " text-align: center;" >> index.html
echo " padding: 0 20px;" >> index.html
echo " padding-bottom: 40px;" >> index.html
echo " transition: all .3s;" >> index.html
echo " }" >> index.html
echo " .instance-card__name {" >> index.html
echo " font-weight: 700;" >> index.html
echo " font-size: 24px;" >> index.html
echo " color: #6944ff;" >> index.html
echo " margin-bottom: 15px;" >> index.html
echo " }" >> index.html
echo " .instance-card-inf__item {" >> index.html
echo " padding: 10px 35px;" >> index.html
echo " min-width: 150px;" >> index.html
echo " }" >> index.html
echo " .instance-card-inf__title {" >> index.html
echo " font-weight: 700;" >> index.html
echo " font-size: 27px;" >> index.html
echo " color: #324e63;" >> index.html
echo " }" >> index.html
echo " .instance-card-inf__txt {" >> index.html
echo " font-weight: 500;" >> index.html
echo " margin-top: 7px;" >> index.html
echo " }" >> index.html
echo " </style>" >> index.html
echo " <title>Amazon EC2 Status</title>" >> index.html
echo "</head>" >> index.html
echo "<body>" >> index.html
echo " <div class=\"wrapper\">" >> index.html
echo " <div class=\"instance-card\">" >> index.html
echo " <div class=\"instance-card__cnt\">" >> index.html
echo " <div class=\"instance-card__name\">Your EC2 Instance is running!</div>" >> index.html
echo " <div class=\"instance-card-inf\">" >> index.html
echo " <div class=\"instance-card-inf__item\">" >> index.html
echo " <div class=\"instance-card-inf__txt\">Instance Id</div>" >> index.html
echo " <div class=\"instance-card-inf__title\">" $META_INST_ID "</div>" >> index.html
echo " </div>" >> index.html
echo " <div class=\"instance-card-inf__item\">" >> index.html
echo " <div class=\"instance-card-inf__txt\">Instance Type</div>" >> index.html
echo " <div class=\"instance-card-inf__title\">" $META_INST_TYPE "</div>" >> index.html
echo " </div>" >> index.html
echo " <div class=\"instance-card-inf__item\">" >> index.html
echo " <div class=\"instance-card-inf__txt\">Availability zone</div>" >> index.html
echo " <div class=\"instance-card-inf__title\">" $META_INST_AZ "</div>" >> index.html
echo " </div>" >> index.html
echo " </div>" >> index.html
echo " </div>" >> index.html
echo " </div>" >> index.html
echo "</body>" >> index.html
echo "</html>" >> index.html
sudo systemctl enable apache2
sudo systemctl restart apache2
5 Auto Scaling Group (ASG) Deployment
Bind the Launch Template, the Target Group, and your scaling policies together.
- Navigate to EC2 Console > Auto Scaling Groups > Create Auto Scaling group.
-
Name:
ubuntu-web-asg. Select template:ubuntu-web-lt. - Network: Select your VPC and at least two subnets across different Availability Zones.
-
Load Balancing: Choose
Attach to an existing load balancer and
select
ubuntu-web-tg. - Health Checks: Enable both EC2 and Elastic Load Balancing (ELB) checks.
-
Group Size: Set Desired:
2, Minimum:1, Maximum:4. - Scaling Policy: Add a Target tracking scaling policy targeting 50% Average CPU Utilization.
6 Live Verification & Load Distribution
- Navigate to Target Groups > ubuntu-web-tg > Targets and confirm instances show Healthy.
- Navigate to Load Balancers > ubuntu-demo-alb and copy the DNS name.
- Open the DNS name in a web browser.
- Refresh the browser window repeatedly the Instance ID and Availability Zone will rotate as the ALB balances traffic across the fleet!
🎉 Elastic Infrastructure Deployed!
Your high-availability web cluster with automated load distribution is active and scalable.