π§ First: what we are building
We will build this real production architecture:
User Browser
β
Application Load Balancer (ALB)
β
Target Group
β
Auto Scaling Group (ASG)
β
EC2 Ubuntu instances with NGINX
Why:
- ALB = traffic control
- ASG = instance control
- DevOps = builds & maintains this so apps never go down
PART 1 β WHY ASG ALONE IS NOT ENOUGH (very important)
Auto Scaling Group does ONLY this:
- Keeps N EC2 instances running
- Replaces a dead instance
Auto Scaling Group does NOT:
- Give users a website address
- Balance traffic
- Check if the application is broken
- Support HTTPS
- Route traffic safely
ALB does:
- Gives ONE stable DNS
- Sends traffic to healthy instances only
- Works across multiple AZs
- Enables zero-downtime deployments
π This is why DevOps ALWAYS uses ALB + ASG together
PART 2 β REGION SETUP (VERY IMPORTANT)
Set region to us-east-2
Top right corner of AWS Console β select:
US East (Ohio) us-east-2
Everything must be created in the same region.
PART 3 β STEP 1: CREATE SECURITY GROUPS
We need 2 security groups:
- For ALB (public)
- For EC2 (private, only ALB allowed)
π Step 1A β Create ALB Security Group
- AWS Console β Search EC2
- Click EC2
- Left menu β Security Groups
- Click Create security group
Fill in:
-
Security group name:
alb-sg - Description: Allow HTTP from internet
- VPC: Default VPC (or your VPC)
Inbound rules
Click Add rule
- Type: HTTP
- Port: 80
- Source: Anywhere-IPv4 (0.0.0.0/0)
Leave outbound as default.
Click Create security group
βοΈ This allows users to reach the ALB.
π Step 1B β Create EC2 Security Group
- Still in Security Groups
- Click Create security group
Fill in:
-
Name:
ec2-web-sg - Description: Allow HTTP only from ALB
- VPC: same as ALB
Inbound rules
Click Add rule
- Type: HTTP
- Port: 80
- Source: Security group
- Select:
alb-sg
Outbound: leave default.
Click Create security group
βοΈ EC2 is protected β only ALB can talk to it.
PART 4 β STEP 2: CREATE LAUNCH TEMPLATE (UBUNTU + NGINX)
Launch Template defines how EC2 instances are created.
π Step 2A β Create Launch Template
- EC2 β Launch Templates
- Click Create launch template
Template name
lt-ubuntu-nginx
AMI
- Click Browse AMIs
- Choose Ubuntu
- Select Ubuntu Server 22.04 LTS
- Architecture: x86_64
Instance type
t2.micro
Key pair
- Choose existing key OR
- Create new (optional if using Session Manager)
Network settings
- Security group: ec2-web-sg
π§Ύ Step 2B β User Data (VERY IMPORTANT)
Scroll down β Advanced details β User data
Paste EXACTLY this:
#!/bin/bash
apt update -y
apt install -y nginx
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)
cat <<EOF > /var/www/html/index.html
<h1>ALB DEMO</h1>
<p>Instance ID: $INSTANCE_ID</p>
<p>Availability Zone: $AZ</p>
<p>Private IP: $IP</p>
EOF
systemctl enable nginx
systemctl restart nginx
This does:
- Installs NGINX
- Creates a web page
- Shows which instance served the request
Click Create launch template
PART 5 β STEP 3: CREATE AUTO SCALING GROUP (ASG)
βοΈ Step 3A β Create ASG
- EC2 β Auto Scaling Groups
- Click Create Auto Scaling group
Name
asg-web
Launch template
- Select:
lt-ubuntu-nginx - Version: Latest
Click Next
Network
- VPC: Default VPC
- Subnets: Select 2 public subnets in different AZs (example: us-east-2a and us-east-2b)
Click Next
Desired capacity
- Desired: 2
- Minimum: 2
- Maximum: 4
Scaling policy:
- Keep default (weβll add later)
Click Skip to review β Create Auto Scaling group
βοΈ You now have 2 Ubuntu EC2 instances running NGINX
PART 6 β STEP 4: CREATE TARGET GROUP
- EC2 β Target Groups
- Click Create target group
Configuration
- Type: Instances
- Name:
tg-web - Protocol: HTTP
- Port: 80
- VPC: same VPC
Health check:
- Path:
/
Click Next
β οΈ Do NOT register instances manually
Click Create target group
PART 7 β STEP 5: ATTACH TARGET GROUP TO ASG
- EC2 β Auto Scaling Groups
- Click
asg-web - Tab: Load balancing
- Click Edit
- Attach target group:
tg-web - Click Update
PART 8 β STEP 6: CREATE APPLICATION LOAD BALANCER (ALB)
- EC2 β Load Balancers
- Click Create load balancer
- Choose Application Load Balancer
Basic config
- Name:
alb-web - Scheme: Internet-facing
- IP type: IPv4
Network
- VPC: same
- Subnets: select same 2 public subnets
Security group
- Select:
alb-sg
Listener
- HTTP : 80
- Forward to:
tg-web
Click Create load balancer
PART 9 β STEP 7: VERIFY & OPEN IN BROWSER
π Check health
- EC2 β Target Groups
- Click
tg-web - Tab: Targets
You should see:
2 instances β Healthy
π Open in browser
- EC2 β Load Balancers
- Click
alb-web - Copy DNS name
Paste into browser:
http://<ALB-DNS-NAME>
You should see:
- Instance ID
- AZ
- Private IP
PART 10 β DEMOS TO SHOW βPOWER OF ALBβ
Demo 1 β Load balancing
- Refresh page multiple times
- Instance ID changes
Demo 2 β High availability
- EC2 β terminate one instance
- Refresh browser β still works
- ASG creates new instance automatically
Demo 3 β Health check
- Stop nginx on one instance
- Target becomes unhealthy
- ALB stops sending traffic to it
PART 11 β DEVOPS ROLE & TEAM STRUCTURE
DevOps responsibilities here:
- Design ALB + ASG
- Secure networking
- Ensure uptime
- Enable scaling
- Prepare HTTPS, monitoring, CI/CD
Who owns this in companies:
| Team | Owns |
|---|---|
| DevOps / Platform | ALB, ASG, VPC |
| Backend | App code |
| Security | WAF, TLS |
| SRE | Reliability (if exists) |
Team size (real life):
- 1 DevOps per 8β12 engineers
FINAL INTERVIEW SENTENCE
βAuto Scaling keeps instances running.
Application Load Balancer keeps the application available.
DevOps builds this platform so developers focus only on code.β
π§ͺ LAB: Application Load Balancer + Auto Scaling Group (REAL DEMO)
π― Lab Goal
By the end of this lab, you will:
- Understand why ALB is needed even when ASG exists
- See real EC2 instances behind ALB
- Prove load balancing + self-healing
- Learn IMDSv2 (modern AWS requirement)
- Understand why AMIs matter in Auto Scaling
ποΈ Architecture
Browser
|
ALB (DNS name)
|
Target Group
|
Auto Scaling Group
|
EC2 (Nginx + PHP)
|
AWS Metadata (IMDSv2)
πΉ PART 1 β Create Base EC2 Instance (Golden Instance)
Step 1: Launch EC2
- AMI: Ubuntu 22.04
- Instance type:
t2.micro -
Security Group:
- Allow HTTP (80) from
0.0.0.0/0 - Allow SSH (22) from your IP
- Allow HTTP (80) from
Subnet: public
SSH into instance:
ssh ubuntu@<EC2_PUBLIC_IP>
πΉ PART 2 β Install Nginx + PHP (Web Stack)
sudo apt update
sudo apt install -y nginx php-fpm
Verify:
systemctl status nginx
ls /run/php/
You should see:
php8.3-fpm.sock
πΉ PART 3 β Configure Nginx
Edit config:
sudo vim /etc/nginx/sites-available/default
DELETE EVERYTHING and paste:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\. {
deny all;
}
}
Test and restart:
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl restart php8.3-fpm
πΉ PART 4 β Create Dynamic Page (IMDSv2 SAFE)
Create app:
sudo vim /var/www/html/index.php
Paste IMDSv2-safe code:
<?php
function meta($path) {
$token = shell_exec("curl -s -X PUT 'http://169.254.169.254/latest/api/token' \
-H 'X-aws-ec2-metadata-token-ttl-seconds: 21600'");
return shell_exec("curl -s -H 'X-aws-ec2-metadata-token: $token' \
http://169.254.169.254/latest/meta-data/$path");
}
?>
<!DOCTYPE html>
<html>
<head>
<title>JumpToTech School - ALB DEMO</title>
</head>
<body>
<h1>JumpToTech School - ALB DEMO</h1>
<p><b>Instance ID:</b> <?php echo meta("instance-id"); ?></p>
<p><b>Availability Zone:</b> <?php echo meta("placement/availability-zone"); ?></p>
<p><b>Private IP:</b> <?php echo meta("local-ipv4"); ?></p>
<p><b>Hostname:</b> <?php echo gethostname(); ?></p>
<p><b>Generated:</b> <?php echo date("Y-m-d H:i:s"); ?></p>
</body>
</html>
Test locally:
curl localhost
β You must see Instance ID, AZ, Private IP
πΉ PART 5 β Create AMI (CRITICAL STEP)
This instance is now your golden image.
AWS Console:
- EC2 β Instances
- Select instance
- Actions β Image and templates β Create image
- Name:
alb-demo-nginx-php-imdsv2
Wait until AMI = Available
πΉ PART 6 β Create Launch Template
- EC2 β Launch Templates β Create
- AMI: new AMI
- Instance type:
t2.micro - Security Group: HTTP + SSH
- Save template
πΉ PART 7 β Create Auto Scaling Group
- Auto Scaling β Create ASG
- Select Launch Template
- Subnets: at least 2 AZs
- Desired:
2 - Min:
1 - Max:
3
πΉ PART 8 β Create Target Group
- Type: Instance
- Protocol: HTTP
- Port: 80
- Health check path:
/
πΉ PART 9 β Create Application Load Balancer
- Type: Application Load Balancer
- Scheme: Internet-facing
- Listener: HTTP 80
- AZs: same as ASG
- Listener β Forward to Target Group
πΉ PART 10 β Attach ASG to Target Group
- ASG β Edit
- Load balancing β Attach existing target group
- Save
Wait until:
- Targets = healthy
πΉ PART 11 β FINAL DEMO (THIS IS THE MAGIC)
Open ALB DNS:
alb-web-xxxx.us-east-2.elb.amazonaws.com
Refresh page multiple times.
You will see:
- Instance ID changes
- Private IP changes
- AZ changes
Terminate one instance:
- ASG creates new one
- Refresh page β new Instance ID
π WHAT DEVOPS MUST EXPLAIN (IMPORTANT)
- ALB does traffic routing
- ASG does instance lifecycle
- Instances are stateless
- Metadata proves which server handled request
- AMI ensures identical infrastructure
π§ COMMON MISTAKES
| Mistake | Lesson |
|---|---|
| Edit one EC2 | ASG ignores it |
| IMDS empty | IMDSv2 required |
| ALB shows old data | Old AMI |
| One AZ only | No HA |
π§ͺ OPTIONAL EXTENSIONS (NEXT LABS)
- ALB stickiness ON vs OFF
- Deregistration delay demo
- Blue/Green deployment
- CloudWatch ALB metrics
- Broken AMI debugging lab
β FINAL CHECKLIST (INTERVIEW READY)
- Can explain ALB vs ASG β
- Can trace traffic path β
- Can debug empty metadata β
- Can explain IMDSv2 β
- Can explain AMI importance β



Top comments (0)