Skip to content

Latest commit

 

History

History

README.md

Horizontal Scalability Demo

AWS ECS Docker Python

Overview

This hands-on workshop demonstrates horizontal scaling using AWS ECS Fargate, Application Load Balancer, and autoscaling. Students will deploy a microservices architecture, configure load balancing, implement CPU-based autoscaling, and observe scaling behavior under load.

Learning Objectives

  • Deploy containerized microservices using AWS CDK (Infrastructure as Code)
  • Configure Application Load Balancers for traffic distribution
  • Implement CPU-based autoscaling policies
  • Monitor and observe scaling behavior with CloudWatch
  • Perform load testing to trigger autoscaling events
  • Understand horizontal scaling patterns and best practices

Architecture

graph TB
    %% Traffic flow
    User("Users") --> ALB(["Application Load Balancer"])
    ALB --> Frontend["Frontend Service<br>Ruby on Rails"]
    Frontend --> NodeJS["NodeJS Service<br>Backend API"]
    Frontend --> Crystal["Crystal Service<br>Backend API"]

    %% ECS services
    subgraph ecs_cluster ["ECS Cluster"]
        direction TB
        Frontend
        NodeJS
        Crystal
    end

    %% Autoscaling feedback loop
    subgraph auto_scaling ["Auto Scaling"]
        direction TB
        ASG{{"Auto Scaling Group"}}
        CW[["CloudWatch Metrics"]]
        ASG -.->|"Monitors"| Frontend
        CW -.->|"Triggers"| ASG
    end

Loading

Prerequisites

  • AWS Account with appropriate permissions
  • AWS CLI configured with credentials
  • Python 3.9+
  • Node.js 14+
  • Docker (optional, for local testing)
  • Basic understanding of containers and AWS services

Workshop Structure

This workshop is organized into phases:

  1. Prerequisites and Setup - Environment configuration
  2. Platform Infrastructure - VPC, ECS Cluster, networking
  3. Frontend Deployment - Deploy the main application
  4. Backend Services - Deploy supporting microservices
  5. Manual Scaling - Scale services manually
  6. Autoscaling - Configure and test automatic scaling
  7. Load Testing - Trigger scaling events
  8. Cleanup - Remove all resources

Quick Start

Option 1: Automated Setup (Recommended for Quick Demo)

# Clone the repository
git clone https://github.com/gamaware/system-design-course.git
cd system-design-course/01-introduction-horizontal-scalability

# Run quick start script
chmod +x quick-start.sh
./quick-start.sh

Option 2: Step-by-Step Workshop (Recommended for Learning)

Follow the detailed guides:

Services Architecture

Frontend Service (Ruby on Rails)

  • Purpose: Main web interface
  • Technology: Ruby on Rails
  • Port: 3000
  • Scaling: Horizontal with ALB

NodeJS Service

  • Purpose: Backend API service
  • Technology: Node.js/Express
  • Port: 3000
  • Features: Service discovery integration

Crystal Service

  • Purpose: High-performance backend API
  • Technology: Crystal language
  • Port: 3000
  • Features: Low latency responses

Key Features

Infrastructure as Code (AWS CDK)

  • Python-based CDK stacks
  • Reproducible deployments
  • Version-controlled infrastructure
  • Easy teardown and recreation

Horizontal Scaling

  • ECS Fargate for serverless containers
  • Application Load Balancer for traffic distribution
  • Target tracking autoscaling policies
  • CloudWatch metrics integration

Observability

  • CloudWatch Logs for application logs
  • CloudWatch Metrics for performance monitoring
  • Service discovery for microservices communication
  • Real-time scaling visualization

Workshop Phases

Phase 1: Prerequisites and Setup

# Activate workshop environment
source activate.sh

# Configure AWS credentials
aws configure

# Bootstrap CDK
cdk bootstrap

Phase 2: Deploy Platform Infrastructure

cd ecsdemo-platform/cdk
cdk deploy --require-approval never

Creates:

  • VPC with public/private subnets
  • ECS Cluster
  • Security Groups
  • Service Discovery namespace
  • Bastion host (optional)

Phase 3: Deploy Frontend Service

cd ../../ecsdemo-frontend/cdk
cdk deploy --require-approval never

Creates:

  • Application Load Balancer
  • ECS Service with Fargate tasks
  • Target Group
  • CloudWatch Log Group

Phase 4: Deploy Backend Services

# Deploy NodeJS service
cd ../../ecsdemo-nodejs/cdk
cdk deploy --require-approval never

# Deploy Crystal service
cd ../../ecsdemo-crystal/cdk
cdk deploy --require-approval never

Phase 5: Manual Scaling

# Scale frontend to 3 tasks
aws ecs update-service \
  --cluster container-demo \
  --service ecsdemo-frontend \
  --desired-count 3

# Verify scaling
aws ecs describe-services \
  --cluster container-demo \
  --services ecsdemo-frontend \
  --query 'services[0].desiredCount'

Phase 6: Configure Autoscaling

# Register scalable target
aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --scalable-dimension ecs:service:DesiredCount \
  --resource-id service/container-demo/ecsdemo-frontend \
  --min-capacity 1 \
  --max-capacity 10

# Create scaling policy
aws application-autoscaling put-scaling-policy \
  --service-namespace ecs \
  --scalable-dimension ecs:service:DesiredCount \
  --resource-id service/container-demo/ecsdemo-frontend \
  --policy-name cpu-scaling-policy \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration \
  '{"TargetValue":50.0,"PredefinedMetricSpecification":{"PredefinedMetricType":"ECSServiceAverageCPUUtilization"},"ScaleInCooldown":30,"ScaleOutCooldown":30}'

Phase 7: Load Testing

# Get ALB URL
ALB_URL=$(aws elbv2 describe-load-balancers \
  --query 'LoadBalancers[0].DNSName' \
  --output text)

# Run load test with siege
siege -c 200 -t 2m http://$ALB_URL

# Monitor scaling in real-time
watch -n 5 'aws ecs describe-services \
  --cluster container-demo \
  --services ecsdemo-frontend \
  --query "services[0].desiredCount"'

Monitoring and Observability

CloudWatch Metrics

# View CPU utilization
aws cloudwatch get-metric-statistics \
  --namespace AWS/ECS \
  --metric-name CPUUtilization \
  --dimensions Name=ServiceName,Value=ecsdemo-frontend \
  --start-time $(date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 60 \
  --statistics Average

CloudWatch Logs

# Stream logs from frontend service
awslogs get /ecs/ecsdemo-frontend --watch

Service Health

# Check service status
aws ecs describe-services \
  --cluster container-demo \
  --services ecsdemo-frontend ecsdemo-nodejs ecsdemo-crystal

Scaling Policies

CPU-Based Scaling

Target: 50% CPU utilization Scale Out: Add tasks when CPU > 50% Scale In: Remove tasks when CPU < 50% Cooldown: 30 seconds

Memory-Based Scaling (Optional)

Target: 80% memory utilization Scale Out: Add tasks when memory > 80% Scale In: Remove tasks when memory < 80%

Troubleshooting

Services Not Starting

# Check service events
aws ecs describe-services \
  --cluster container-demo \
  --services ecsdemo-frontend \
  --query 'services[0].events[0:5]'

# Check task status
aws ecs list-tasks \
  --cluster container-demo \
  --service-name ecsdemo-frontend

# View task logs
aws logs tail /ecs/ecsdemo-frontend --follow

Load Balancer Issues

# Check target health
aws elbv2 describe-target-health \
  --target-group-arn <target-group-arn>

# Check ALB listeners
aws elbv2 describe-listeners \
  --load-balancer-arn <alb-arn>

Autoscaling Not Working

# Check scaling policies
aws application-autoscaling describe-scaling-policies \
  --service-namespace ecs

# Check scaling activities
aws application-autoscaling describe-scaling-activities \
  --service-namespace ecs \
  --resource-id service/container-demo/ecsdemo-frontend

Cleanup

Manual Cleanup

# Delete services in reverse order
cd ecsdemo-crystal/cdk && cdk destroy --force
cd ../../ecsdemo-nodejs/cdk && cdk destroy --force
cd ../../ecsdemo-frontend/cdk && cdk destroy --force
cd ../../ecsdemo-platform/cdk && cdk destroy --force

# Deactivate environment
source deactivate.sh

Cost Considerations

Estimated costs for running this workshop:

  • ECS Fargate tasks: ~$0.04/hour per task
  • Application Load Balancer: ~$0.025/hour
  • NAT Gateway: ~$0.045/hour
  • Data transfer: Minimal for testing

Total estimated cost: ~$0.50-$1.00 per hour

💡 Tip: Always run cleanup after completing the workshop to avoid unnecessary charges.

Key Concepts

Horizontal Scaling Concepts

  • Adding more instances of the same service
  • Distributes load across multiple containers
  • Increases availability and fault tolerance
  • Scales based on demand

Vertical Scaling (Not Covered)

  • Increasing resources (CPU/memory) of existing instances
  • Limited by instance size constraints
  • Requires downtime for changes

Autoscaling Strategies

  • Target Tracking: Maintain specific metric target
  • Step Scaling: Scale based on metric thresholds
  • Scheduled Scaling: Scale at specific times

Load Balancing

  • Round Robin: Distribute requests evenly
  • Least Outstanding Requests: Send to least busy target
  • Health Checks: Remove unhealthy targets automatically

Additional Resources

Workshop Guides

Author

Created by Alex Garcia

License

This project is licensed under the MIT License - see the LICENSE file for details.