Compute & Database
Launch EC2 instances, configure Auto Scaling Groups, set up RDS PostgreSQL, and load-balance with ALB.
What You'll Learn
With your networking in place, it's time to deploy compute and database resources. You'll launch EC2 instances with Auto Scaling, set up RDS PostgreSQL, and load-balance with ALB.
| Azure | AWS | Notes |
|---|---|---|
Virtual Machine | EC2 | Nearly identical concept |
VMSS | Auto Scaling Group | ASG + Launch Template ≈ VMSS |
Azure DB for PostgreSQL | RDS PostgreSQL | Very similar. AWS has DB Subnet Groups |
App Gateway | ALB | ALB is simpler; App Gateway has built-in WAF |
Managed Identity | IAM Instance Profile | Attach IAM Role to EC2 for permissions |
Step 1: RDS PostgreSQL
RDS (Relational Database Service) is a managed database. AWS handles backups, patching, and failover — you just connect and query.
Key Concepts
- DB Subnet Group: Tells RDS which subnets to use (must span 2+ AZs)
- Multi-AZ: Automatic failover to a standby in another AZ (production feature)
- Instance Class:
db.t3.microis free-tier eligible
Azure Database for PostgreSQL Flexible Server uses VNet integration or Private Endpoints for network isolation. AWS RDS uses Security Groups + DB Subnet Groups — functionally equivalent, different mechanism.
DBInstance:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: aws-sandbox-db
Engine: postgres
EngineVersion: '15.4'
DBInstanceClass: db.t3.micro
DBName: aws_sandbox
MasterUsername: dbadmin
MasterUserPassword: !Ref DBMasterPassword
AllocatedStorage: 20
StorageType: gp3
DBSubnetGroupName: !Ref DBSubnetGroup
VPCSecurityGroups:
- !ImportValue aws-sandbox-RDSSecurityGroupId
MultiAZ: false
PubliclyAccessible: falseStep 2: Application Load Balancer
The ALB distributes incoming HTTP/HTTPS traffic across your EC2 instances. It sits in public subnets and forwards to a Target Group.
Components
🔀 ALB
The load balancer itself. Lives in public subnets, has its own DNS name.
🎯 Target Group
A collection of targets (EC2 instances) with health check configuration.
👂 Listener
Listens on a port (80/443) and routes traffic to the target group.
Health Checks
The ALB pings /health on each instance every 30 seconds. If an instance fails 3 checks, it gets removed from rotation.
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: 3000
Protocol: HTTP
VpcId: !ImportValue aws-sandbox-VpcId
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3Step 3: EC2 + Auto Scaling Group
Instead of launching individual EC2 instances, we use a Launch Template+ Auto Scaling Group (ASG) to automatically manage instance count.
Launch Template
Defines what to launch: AMI, instance type, security group, IAM role, and User Data (a startup script that runs on first boot).
Auto Scaling Group
Defines how many to launch: minimum, maximum, and desired count. It also handles replacement of unhealthy instances.
VMSS comparison: An Azure VMSS bundles the image and scaling config into one resource. AWS separates them: Launch Template (image config) + ASG (scaling config). Same result, different structure.
User Data Script
User Data is a bash script that runs when the instance first boots. We use it to install the CodeDeploy agent, Node.js, and set up environment variables.
#!/bin/bash
# User Data — runs on first boot
# Install CodeDeploy Agent
yum install -y ruby wget
cd /tmp
wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/latest/install
chmod +x ./install && ./install auto
# Install Node.js
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs
npm install -g pm2
# Create environment file with RDS connection details
cat > /home/ec2-user/.env << EOF
NODE_ENV=production
PORT=3000
DB_HOST=your-rds-endpoint.rds.amazonaws.com
DB_PORT=5432
DB_NAME=aws_sandbox
DB_USER=dbadmin
DB_PASSWORD=YourPassword
EOFScaling Policies
Target Tracking scales based on a metric. We set CPUUtilization target to 70%— AWS adds instances when CPU exceeds 70% and removes them when it drops below.
Hands-On: Deploy Compute Stack and Test Load Balancing
After deploying stacks 1-5, test that the ALB distributes traffic:
# Get ALB DNS name
ALB_DNS=$(aws cloudformation describe-stacks \
--stack-name aws-sandbox-alb \
--query 'Stacks[0].Outputs[?OutputKey==`ALBDNSName`].OutputValue' \
--output text)
# Hit the info endpoint multiple times
# Watch the hostname change — that's load balancing!
for i in {1..5}; do
echo "Request $i:"
curl -s "http://$ALB_DNS/api/info" | python3 -c "
import sys,json
d=json.load(sys.stdin)
print(f" Hostname: {d['hostname']}, CPUs: {d['cpus']}")"
sleep 1
doneEach request should show a different hostname — proving the ALB is routing across your ASG instances.
Key Takeaways
- RDS handles database management — you focus on queries, AWS handles backups and patching
- ALB + Target Group pattern is the standard for HTTP load balancing
- Launch Template + ASG = reproducible, auto-healing, auto-scaling compute
- User Data scripts are powerful but run only on first boot
- The
/healthendpoint is critical — it's how the ALB knows which instances are alive