
Building for the Cloud
AWS offers 200+ services. The challenge isn't what to use—it's knowing when and how to combine them effectively.
The Core Services
| Service | Purpose | When to Use |
|---|---|---|
| EC2 | Virtual servers | Full control needed |
| Lambda | Serverless compute | Event-driven, short tasks |
| S3 | Object storage | Files, backups, static sites |
| RDS | Managed databases | Relational data |
| VPC | Network isolation | Security boundaries |
Pattern 1: Three-Tier Architecture
The classic, battle-tested approach:
┌─────────────────────────────────────────┐
│ Application Load Balancer │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ EC2 Auto Scaling Group │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ Web │ │ Web │ │ Web │ │ Web │ │
│ └─────┘ └─────┘ └─────┘ └─────┘ │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ RDS Multi-AZ (Primary + Standby) │
└─────────────────────────────────────────┘
Pattern 2: Serverless Event-Driven
Zero servers to manage:
API Gateway → Lambda → DynamoDB
↓
SQS Queue → Lambda → S3
↓
SNS → Email
Example Lambda Function
import json
import boto3
def handler(event, context):
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')
response = table.put_item(
Item={
'user_id': event['user_id'],
'name': event['name'],
'created_at': str(datetime.now())
}
)
return {
'statusCode': 200,
'body': json.dumps('User created!')
}
Pattern 3: Microservices with ECS
Container orchestration made simple:
# ECS Task Definition
{
"family": "web-service",
"containerDefinitions": [
{
"name": "web",
"image": "my-app:latest",
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000
}
],
"memory": 512,
"cpu": 256
}
]
}
Cost Optimization Tips
1. Right-Size Instances
Don't pay for unused capacity: - Use Compute Optimizer recommendations - Start small, scale up as needed - Consider Graviton (ARM) instances for 40% savings
2. Reserved vs Spot vs On-Demand
| Type | Savings | Best For |
|---|---|---|
| On-Demand | 0% | Unpredictable workloads |
| Reserved | 30-70% | Steady-state production |
| Spot | Up to 90% | Fault-tolerant batch jobs |
3. S3 Storage Classes
Frequent Access → S3 Standard
Infrequent → S3 IA (40% cheaper)
Archive → S3 Glacier (80% cheaper)
Deep Archive → Glacier Deep (95% cheaper)
Security Best Practices
- 🔐 IAM Least Privilege - Only grant what's needed
- 🛡️ Security Groups - Stateful firewalls
- 📝 CloudTrail - Audit all API calls
- 🔍 GuardDuty - Threat detection
My Go-To Stack
For most new projects, I start with:
- Route 53 - DNS
- CloudFront - CDN
- ALB - Load balancing
- ECS Fargate - Containers without servers
- RDS Aurora - Managed MySQL/PostgreSQL
- ElastiCache - Redis for caching
- S3 - Static assets
Build for scale from day one, but only pay for what you use!