The "Big Three" (AWS, GCP, Azure) plus strong alternatives. Understanding their service ecosystems lets you pick the right provider and avoid vendor lock-in traps.
| Category | AWS | GCP | Azure | DigitalOcean |
|---|---|---|---|---|
| Compute (VMs) | EC2 | Compute Engine | Virtual Machines | Droplets |
| Containers | ECS / EKS | Cloud Run / GKE | ACI / AKS | DOKS / App Platform |
| Serverless | Lambda | Cloud Functions | Azure Functions | Functions (beta) |
| Object Storage | S3 | Cloud Storage | Blob Storage | Spaces |
| SQL Database | RDS / Aurora | Cloud SQL / Spanner | Azure SQL | Managed Databases |
| NoSQL | DynamoDB | Firestore / Bigtable | Cosmos DB | MongoDB (managed) |
| CDN | CloudFront | Cloud CDN | Azure CDN | Spaces CDN |
| DNS | Route 53 | Cloud DNS | Azure DNS | DNS (basic) |
| Load Balancer | ALB / NLB | Cloud Load Balancing | Azure LB | Load Balancers |
| Secrets | Secrets Manager | Secret Manager | Key Vault | — |
| Monitoring | CloudWatch | Cloud Monitoring | Azure Monitor | Built-in metrics |
| IaC | CloudFormation | Deployment Manager | ARM / Bicep | Terraform only |
| Model | Description | Savings | Commitment |
|---|---|---|---|
| On-Demand | Pay by the hour/second, no commitment | 0% (baseline) | None |
| Reserved / Committed | 1-3 year commitment for lower rate | 30-72% | 1-3 years |
| Spot / Preemptible | Unused capacity, can be terminated anytime | 60-90% | None (but unreliable) |
| Savings Plans | Commit to $/hr spend, flexible instance types | 20-50% | 1-3 years |
Deploying a web app with EC2 + RDS + S3 + CloudFront:
# Architecture:
# CloudFront (CDN) → ALB → EC2 (app) → RDS (PostgreSQL)
# → S3 (static assets/uploads)
# Step 1: Create VPC with public/private subnets
aws ec2 create-vpc --cidr-block 10.0.0.0/16
# (In practice, use Terraform — shown in Chapter 14)
# Step 2: Launch RDS in private subnet
aws rds create-db-instance \
--db-instance-identifier myapp-db \
--db-instance-class db.t3.micro \
--engine postgres \
--engine-version 16 \
--master-username admin \
--master-user-password "$(openssl rand -base64 24)" \
--allocated-storage 20 \
--no-publicly-accessible \
--vpc-security-group-ids sg-xxxxx
# Step 3: Create S3 bucket for assets
aws s3 mb s3://myapp-assets-prod
aws s3api put-bucket-policy --bucket myapp-assets-prod \
--policy '{"Statement":[{"Effect":"Allow","Principal":"*","Action":"s3:GetObject","Resource":"arn:aws:s3:::myapp-assets-prod/*"}]}'
# Step 4: Create CloudFront distribution
aws cloudfront create-distribution \
--origin-domain-name myapp-assets-prod.s3.amazonaws.com \
--default-root-object index.html
# Step 5: Set up ALB + EC2 (use launch template + auto-scaling group)
# Step 6: Configure Route 53 to point domain to CloudFront
# Architecture:
# Load Balancer → Droplet(s) → Managed PostgreSQL
# → Spaces (S3-compatible storage)
# Step 1: Create a Droplet
doctl compute droplet create myapp-web \
--image ubuntu-22-04-x64 \
--size s-1vcpu-2gb \
--region fra1 \
--ssh-keys YOUR_KEY_FINGERPRINT
# Step 2: Create managed database
doctl databases create myapp-db \
--engine pg \
--version 16 \
--size db-s-1vcpu-1gb \
--region fra1 \
--num-nodes 1
# Step 3: Create Spaces bucket (S3-compatible)
# Done via web console or s3cmd with DO endpoint
# Step 4: Create load balancer
doctl compute load-balancer create \
--name myapp-lb \
--region fra1 \
--forwarding-rules "entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:YOUR_CERT" \
--droplet-ids DROPLET_ID
# Step 5: Point domain DNS to load balancer IP