Deploying Scalable Applications in Private Subnets with Bastion Host and ALB on AWS


π Deploying Web Apps in Private Subnets with Bastion Host and Load Balancer (Step-by-Step on AWS)
A complete walkthrough of deploying secure, auto-scaled web apps in private subnets using EC2, Auto Scaling, Load Balancer, and a Bastion Host β all inside a custom VPC.
π Overview
In this blog, I'll walk you through how I created a secure AWS infrastructure where:
EC2 instances are in private subnets.
A bastion host is used to access them.
A Layer 7 (HTTP) Application Load Balancer routes traffic.
Auto Scaling Groups manage dynamic EC2 instances.
Weβll deploy a basic Python HTTP server in one EC2 instance and observe how load balancing works with public-facing ALBs routing to private instances.
π§± Step 1: Create a VPC with Subnets
β Create VPC:
Name:
demo-vpc
CIDR:
10.0.0.0/16
β Create Subnets:
Private Subnets:
private1-east-1a
β AZ:us-east-1a
private2-east-1b
β AZ:us-east-1b
Public Subnet:
public1-east-1a
β AZ:us-east-1a
π¦ Step 2: Launch Template for Auto Scaling
β Create a Launch Template:
AMI: Ubuntu
Instance Type:
t2.micro
Key Pair:
east1key
Security Group:
aws-prod-example
Allow SSH (port 22) from anywhere
Allow TCP 8000 (We'll secure this later) for web server
π Step 3: Auto Scaling Group (ASG)
β Configure Auto Scaling Group:
Name:
aws-prod-example
Launch Template: use the one above
VPC:
demo-vpc
Subnets:
private1-east-1a
,private2-east-1b
Desired Capacity:
2
Max Capacity:
4
Load Balancer: β (not added yet)
β‘οΈ Result: Two EC2 instances are created inside private subnets with no public IPs.
π Step 4: Bastion Host for Private Access
Because our EC2s are in private subnets, we can't SSH into them directly. So we set up a bastion host.
β Bastion Host EC2:
AMI: Ubuntu
Subnet:
public1-east-1a
Security Group: Allow SSH (port 22) from anywhere
Key Pair:
east1key
β
Copy east1key.pem
to Bastion Host:
You can use scp
or any file transfer tool.
scp -i east1key.pem east1key.pem ubuntu@<bastion-public-ip>:/home/ubuntu/
chmod 400 east1key.pem
β SSH into Private EC2 from Bastion:
ssh -i east1key.pem ubuntu@<private-ec2-ip>
π Production Tip: Lock down EC2 port 8000 to the ALB's security group post-setup
Restrict Bastionβs SSH access to your IP in production
π§ͺ Step 5: Deploy a Simple Web App
On one of the private EC2s, weβll deploy a basic Python server:
β
Create index.html
:
<!DOCTYPE html>
<html>
<body>
<h1>My First AWS PROJECT to demonstrate apps in private subnet</h1>
</body>
</html>
β Start the Python HTTP Server:
python3 -m http.server 8000
Only one EC2 serves this page; the other EC2 is left idle to simulate an unreachable server.
βοΈ Step 6: Application Load Balancer (ALB)
Now we expose our private EC2s to the internet using a Layer 7 ALB.
β Create Target Group:
Name:
aws-prod-example
Target Type: Instances
Protocol: HTTP
Port: 8000
VPC:
demo-vpc
Register both EC2s
β Create Load Balancer:
Type: Application Load Balancer
Scheme: Internet-facing
Subnets: Public subnets of the VPC
Security Group:
- β
Allow port 80 (HTTP) from
0.0.0.0/0
- β
Allow port 80 (HTTP) from
β Listener Rule:
- Forward all HTTP traffic to
aws-prod-example
Target Group
π Security Group Summary
Component | Inbound Rule | Why? |
ALB | Port 80 from 0.0.0.0/0 | Accept HTTP from internet |
EC2s (ASG) | Port 8000 (from ALB only) | Receive traffic from ALB |
Bastion Host | Port 22 from 0.0.0.0/0 | SSH access to reach private EC2s |
π‘ Pro Tip: In production, lock down port 8000 to only allow the Load Balancer's security group.
β Result
Visiting the DNS of the Load Balancer shows the HTML page.
50% of requests fail (because only one EC2 is serving), simulating unbalanced load distribution.
This demonstrates how load balancing distributes traffic and the importance of app health in target groups.
π‘ ALB health checks would mark the idle instance as unhealthy, routing 100% traffic to the active instance.
π Key Learnings
π Private EC2s are safe from public access, enhancing security.
πͺ Bastion hosts allow secure admin access to private instances.
βοΈ Load balancers make private services accessible without exposing EC2s directly.
π Auto Scaling helps scale app servers up/down based on traffic.
π§ Final Thoughts
This project is a great starting point for understanding real-world cloud architecture. You've practiced:
Networking (VPCs, subnets, security groups)
Auto Scaling
Bastion host setup
Load balancing
Web app deployment
π’ Real-world analogy
Imagine a secure office building:
π§ Receptionist (ALB) accepts visitor requests at front desk (port 80)
πͺ Receptionist walks to employee office (port 8000) with the request
π©βπΌ Employee sends response back through receptionist
π‘οΈ Visitors never enter employee offices directly
Thanks so much for reading! π
If you enjoyed this, feel free to like, share, or follow for more AWS/DevOps content.
Subscribe to my newsletter
Read articles from Ayush Shrotriya directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
