ECS Manual Deployment Guide - AWS Console
Resources Created by the Script and Their Relationships
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Internet Users │
└────────────────────────┬────────────────────────────────────┘
│ HTTP Port 80
▼
┌────────────────────────────────────┐
│ Application Load Balancer (ALB) │
│ music-app-alb │
└────────────────────────────────────┘
│
Port 5000
▼
┌────────────────────────────────────┐
│ Target Group (music-app-tg) │
│ Health Check: /login │
└────────────────────────────────────┘
│
Routes to
▼
┌────────────────────────────────────┐
│ ECS Service (music-app-service) │
│ Desired Count: 1 task │
└────────────────────────────────────┘
│
Runs tasks from
▼
┌────────────────────────────────────┐
│ Task Definition (music-app-task) │
│ CPU: 256, Memory: 512 │
│ Image: ECR music-app:latest │
└────────────────────────────────────┘
┌─────────────────────────────┐
│ Uses Docker Image from ECR │
│ music-app:latest │
└─────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ Application Dependencies │
├─────────────────────────────────────────────────┤
│ • DynamoDB: Login & Music tables (data) │
│ • S3: music-catalog-s4084267 (album images) │
│ • CloudWatch Logs: /ecs/music-app (logging) │
│ • IAM Role: LabRole (task permissions) │
└─────────────────────────────────────────────────┘
Resources Summary
| Resource | Name | Purpose |
|---|---|---|
| ECR | music-app | Container image registry for Flask app |
| CloudWatch | /ecs/music-app | Application logs storage |
| DynamoDB | Login | User authentication data |
| DynamoDB | Music | Song catalog |
| S3 | music-catalog-s4084267 | Album cover images |
| IAM Role | LabRole | Task permissions for DynamoDB, S3, Logs |
| VPC | Default VPC | Network isolation |
| Security Group | music-app-ecs-sg | Firewall rules (ports 80, 5000) |
| ALB | music-app-alb | Load balancer for internet traffic |
| Target Group | music-app-tg | Routes ALB traffic to ECS tasks |
| ECS Cluster | music-app-cluster | Container orchestration |
| Task Definition | music-app-task | Container configuration template |
| ECS Service | music-app-service | Maintains running tasks |
Step-by-Step Manual Deployment via AWS Console
Phase 1: Preparation & Data Storage
Step 1: Create DynamoDB Tables
Table 1: Login Table
- Go to DynamoDB Console → Create Table
- Table name:
Login - Partition key:
email(String) - Billing mode: Pay-per-request
- Add Global Secondary Index:
- Index name:
UsernameIndex - Partition key:
username(String) - Projection: All
- Index name:
- Click Create Table
Table 2: Music Table
- Go to DynamoDB Console → Create Table
- Table name:
Music - Partition key:
artist(String) - Sort key:
song_key(String) - Billing mode: Pay-per-request
- Add Local Secondary Index:
- Index name:
ArtistYearIndex - Sort key:
year(String) - Projection: All
- Index name:
- Add Global Secondary Indexes:
- Index 1: Name
AlbumIndex, Partition:album, Sort:song_key, Project All - Index 2: Name
TitleIndex, Partition:title, Sort:artist, Project All
- Index 1: Name
- Click Create Table
Step 2: Create S3 Bucket
- Go to S3 Console → Create Bucket
- Bucket name:
music-catalog-s4084267 - Region:
us-east-1 - Keep all default settings
- Click Create Bucket
Step 3: Create CloudWatch Log Group
- Go to CloudWatch Console → Log Groups → Create Log Group
- Log group name:
/ecs/music-app - Retention: Never expire (or your preference)
- Click Create
Phase 2: Container Registry
Step 4: Create ECR Repository
- Go to ECR Console → Create Repository
- Repository name:
music-app - Image tag mutability: Mutable
- Click Create Repository
- You'll see the repository URI:
<account-id>.dkr.ecr.us-east-1.amazonaws.com/music-app
Note: You need to build and push the Docker image locally:
# From project root
docker build -t music-app:latest -f backend/deployment/ecs/Dockerfile .
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker tag music-app:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/music-app:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/music-app:latest
Phase 3: Networking & Security
Step 5: Get Default VPC Information
- Go to VPC Console → Your VPCs
- Find the Default VPC (or your preferred VPC)
- Note the VPC ID:
vpc-xxxxxxxx - Go to Subnets, filter by your VPC
- Note at least 2 public subnet IDs:
subnet-xxxxxxxx
Step 6: Create Security Group
- Go to EC2 Console → Security Groups → Create Security Group
- Security group name:
music-app-ecs-sg - Description:
ECS ALB + task security group for music-app - VPC: Select your default VPC
- Inbound Rules:
- Rule 1: Type: HTTP, Protocol: TCP, Port: 80, Source: 0.0.0.0/0
- Rule 2: Type: Custom TCP, Protocol: TCP, Port: 5000, Source: 0.0.0.0/0
- Click Create Security Group
Phase 4: Load Balancing
Step 7: Create Application Load Balancer
- Go to EC2 Console → Load Balancers → Create Load Balancer
- Choose Application Load Balancer → Create
- Name:
music-app-alb - Scheme: Internet-facing
- IP address type: IPv4
- VPC: Select your default VPC
- Availability Zones: Select at least 2 public subnets
- Security Groups: Select
music-app-ecs-sg - Click Next → Configure Routing
Step 8: Create Target Group
- Target type: IP
- Name:
music-app-tg - Protocol: HTTP
- Port: 5000
- VPC: Your default VPC
- Configure Health Checks:
- Protocol: HTTP
- Path:
/login - Port: 5000
- Interval: 15 seconds
- Healthy threshold: 5
- Unhealthy threshold: 2
- Click Next → Register Targets (leave empty for now)
- Click Create
Step 9: Complete ALB Setup
- Back on the ALB creation page, select the newly created target group
music-app-tg - Click Create Load Balancer
- Wait for status to be Active
- Note the DNS name:
music-app-alb-xxxxxxxx.us-east-1.elb.amazonaws.com
Phase 5: Container Orchestration
Step 10: Create ECS Cluster
- Go to ECS Console → Clusters → Create Cluster
- Cluster configuration:
- Cluster name:
music-app-cluster - Infrastructure: AWS Fargate (serverless)
- Cluster name:
- Click Create
Step 11: Create ECS Task Definition
- Go to ECS Console → Task Definitions → Create New Task Definition
- Task definition family:
music-app-task - Launch type: AWS Fargate
- Operating system: Linux
- CPU: 256 (.25 vCPU)
- Memory: 512 MB
- Task role: Select
LabRole - Task execution role: Select
ecsTaskExecutionRole(if available) or create one withAmazonECSTaskExecutionRolePolicy
Container Settings:
- Click Add Container
- Container name:
music-app - Image URI:
<account-id>.dkr.ecr.us-east-1.amazonaws.com/music-app:latest - Container port: 5000
- Environment variables:
FLASK_SECRET_KEY:dev-secret-keyAWS_REGION:us-east-1S3_BUCKET_NAME:music-catalog-s4084267
- Log configuration:
- Log driver: awslogs
- Log group:
/ecs/music-app - Log stream prefix:
music-app - Region:
us-east-1
- Click Add
- Click Create
Step 12: Create ECS Service
- Go to ECS Console → Clusters → music-app-cluster
- Click Create Service
- Launch type: Fargate
- Task definition:
music-app-task - Revision: Latest
- Service name:
music-app-service - Desired count: 1
- Click Next Step
Network Configuration:
- VPC: Your default VPC
- Subnets: Select 2 public subnets
- Security groups: Select
music-app-ecs-sg - Assign public IP: ENABLED
- Click Next Step
Load Balancing:
- Load balancer type: Application Load Balancer
- Load balancer name:
music-app-alb - Container to load balance:
music-app - Container port: 5000
- Target group name:
music-app-tg - Click Next Step → Next Step → Create Service
Phase 6: IAM Permissions (Pre-requisite)
Note: Ensure LabRole or your task role has these permissions:
- Go to IAM Console → Roles → Select your task role
- Add inline policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:BatchGetItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Resource": [ "arn:aws:dynamodb:us-east-1:*:table/Login", "arn:aws:dynamodb:us-east-1:*:table/Music" ] }, { "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::music-catalog-s4084267", "arn:aws:s3:::music-catalog-s4084267/*" ] }, { "Effect": "Allow", "Action": ["logs:CreateLogStream", "logs:PutLogEvents"], "Resource": "arn:aws:logs:us-east-1:*:log-group:/ecs/music-app:*" } ] }
Step 13: Verify Deployment
- Go to ECS Console → Clusters → music-app-cluster → Services → music-app-service
- Check Tasks tab - wait until at least one task reaches
RUNNINGstatus - Go to Target Groups in EC2 Console →
music-app-tg→ Target health - Wait until target shows
healthy - Open browser and visit:
http://music-app-alb-xxxxxxxx.us-east-1.elb.amazonaws.com - You should see the login page
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Tasks not starting | Container image not in ECR | Push image to ECR first |
| Targets unhealthy | Health check failing | Verify health check path /login responds 200 |
| 503 Service Unavailable | No healthy targets | Check task logs in CloudWatch |
| DynamoDB access denied | IAM role missing permissions | Add DynamoDB permissions to task role |
| S3 access denied | IAM role missing permissions | Add S3 permissions to task role |
Estimated Costs (AWS Free Tier)
- ECS Fargate: 1 task × 512 MB × ~24 hours = Free tier eligible
- ALB: ~$16/month (not free tier)
- DynamoDB: Pay-per-request = minimal cost
- S3: <1GB storage = minimal cost
- CloudWatch Logs: First 5GB/month free
Approximate total if using Free Tier: $16/month for ALB