Back to course
Week 01

ECS_MANUAL_DEPLOYMENT_GUIDE

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

ResourceNamePurpose
ECRmusic-appContainer image registry for Flask app
CloudWatch/ecs/music-appApplication logs storage
DynamoDBLoginUser authentication data
DynamoDBMusicSong catalog
S3music-catalog-s4084267Album cover images
IAM RoleLabRoleTask permissions for DynamoDB, S3, Logs
VPCDefault VPCNetwork isolation
Security Groupmusic-app-ecs-sgFirewall rules (ports 80, 5000)
ALBmusic-app-albLoad balancer for internet traffic
Target Groupmusic-app-tgRoutes ALB traffic to ECS tasks
ECS Clustermusic-app-clusterContainer orchestration
Task Definitionmusic-app-taskContainer configuration template
ECS Servicemusic-app-serviceMaintains running tasks

Step-by-Step Manual Deployment via AWS Console

Phase 1: Preparation & Data Storage

Step 1: Create DynamoDB Tables

Table 1: Login Table

  1. Go to DynamoDB ConsoleCreate Table
  2. Table name: Login
  3. Partition key: email (String)
  4. Billing mode: Pay-per-request
  5. Add Global Secondary Index:
    • Index name: UsernameIndex
    • Partition key: username (String)
    • Projection: All
  6. Click Create Table

Table 2: Music Table

  1. Go to DynamoDB ConsoleCreate Table
  2. Table name: Music
  3. Partition key: artist (String)
  4. Sort key: song_key (String)
  5. Billing mode: Pay-per-request
  6. Add Local Secondary Index:
    • Index name: ArtistYearIndex
    • Sort key: year (String)
    • Projection: All
  7. 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
  8. Click Create Table

Step 2: Create S3 Bucket

  1. Go to S3 ConsoleCreate Bucket
  2. Bucket name: music-catalog-s4084267
  3. Region: us-east-1
  4. Keep all default settings
  5. Click Create Bucket

Step 3: Create CloudWatch Log Group

  1. Go to CloudWatch ConsoleLog GroupsCreate Log Group
  2. Log group name: /ecs/music-app
  3. Retention: Never expire (or your preference)
  4. Click Create

Phase 2: Container Registry

Step 4: Create ECR Repository

  1. Go to ECR ConsoleCreate Repository
  2. Repository name: music-app
  3. Image tag mutability: Mutable
  4. Click Create Repository
  5. 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

  1. Go to VPC ConsoleYour VPCs
  2. Find the Default VPC (or your preferred VPC)
  3. Note the VPC ID: vpc-xxxxxxxx
  4. Go to Subnets, filter by your VPC
  5. Note at least 2 public subnet IDs: subnet-xxxxxxxx

Step 6: Create Security Group

  1. Go to EC2 ConsoleSecurity GroupsCreate Security Group
  2. Security group name: music-app-ecs-sg
  3. Description: ECS ALB + task security group for music-app
  4. VPC: Select your default VPC
  5. 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
  6. Click Create Security Group

Phase 4: Load Balancing

Step 7: Create Application Load Balancer

  1. Go to EC2 ConsoleLoad BalancersCreate Load Balancer
  2. Choose Application Load BalancerCreate
  3. Name: music-app-alb
  4. Scheme: Internet-facing
  5. IP address type: IPv4
  6. VPC: Select your default VPC
  7. Availability Zones: Select at least 2 public subnets
  8. Security Groups: Select music-app-ecs-sg
  9. Click NextConfigure Routing

Step 8: Create Target Group

  1. Target type: IP
  2. Name: music-app-tg
  3. Protocol: HTTP
  4. Port: 5000
  5. VPC: Your default VPC
  6. Configure Health Checks:
    • Protocol: HTTP
    • Path: /login
    • Port: 5000
    • Interval: 15 seconds
    • Healthy threshold: 5
    • Unhealthy threshold: 2
  7. Click NextRegister Targets (leave empty for now)
  8. Click Create

Step 9: Complete ALB Setup

  1. Back on the ALB creation page, select the newly created target group music-app-tg
  2. Click Create Load Balancer
  3. Wait for status to be Active
  4. Note the DNS name: music-app-alb-xxxxxxxx.us-east-1.elb.amazonaws.com

Phase 5: Container Orchestration

Step 10: Create ECS Cluster

  1. Go to ECS ConsoleClustersCreate Cluster
  2. Cluster configuration:
    • Cluster name: music-app-cluster
    • Infrastructure: AWS Fargate (serverless)
  3. Click Create

Step 11: Create ECS Task Definition

  1. Go to ECS ConsoleTask DefinitionsCreate New Task Definition
  2. Task definition family: music-app-task
  3. Launch type: AWS Fargate
  4. Operating system: Linux
  5. CPU: 256 (.25 vCPU)
  6. Memory: 512 MB
  7. Task role: Select LabRole
  8. Task execution role: Select ecsTaskExecutionRole (if available) or create one with AmazonECSTaskExecutionRolePolicy

Container Settings:

  1. Click Add Container
  2. Container name: music-app
  3. Image URI: <account-id>.dkr.ecr.us-east-1.amazonaws.com/music-app:latest
  4. Container port: 5000
  5. Environment variables:
    • FLASK_SECRET_KEY: dev-secret-key
    • AWS_REGION: us-east-1
    • S3_BUCKET_NAME: music-catalog-s4084267
  6. Log configuration:
    • Log driver: awslogs
    • Log group: /ecs/music-app
    • Log stream prefix: music-app
    • Region: us-east-1
  7. Click Add
  8. Click Create

Step 12: Create ECS Service

  1. Go to ECS ConsoleClustersmusic-app-cluster
  2. Click Create Service
  3. Launch type: Fargate
  4. Task definition: music-app-task
  5. Revision: Latest
  6. Service name: music-app-service
  7. Desired count: 1
  8. Click Next Step

Network Configuration:

  1. VPC: Your default VPC
  2. Subnets: Select 2 public subnets
  3. Security groups: Select music-app-ecs-sg
  4. Assign public IP: ENABLED
  5. Click Next Step

Load Balancing:

  1. Load balancer type: Application Load Balancer
  2. Load balancer name: music-app-alb
  3. Container to load balance: music-app
  4. Container port: 5000
  5. Target group name: music-app-tg
  6. Click Next StepNext StepCreate Service

Phase 6: IAM Permissions (Pre-requisite)

Note: Ensure LabRole or your task role has these permissions:

  1. Go to IAM ConsoleRoles → Select your task role
  2. 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

  1. Go to ECS ConsoleClustersmusic-app-clusterServicesmusic-app-service
  2. Check Tasks tab - wait until at least one task reaches RUNNING status
  3. Go to Target Groups in EC2 Console → music-app-tgTarget health
  4. Wait until target shows healthy
  5. Open browser and visit: http://music-app-alb-xxxxxxxx.us-east-1.elb.amazonaws.com
  6. You should see the login page

Troubleshooting

IssueCauseSolution
Tasks not startingContainer image not in ECRPush image to ECR first
Targets unhealthyHealth check failingVerify health check path /login responds 200
503 Service UnavailableNo healthy targetsCheck task logs in CloudWatch
DynamoDB access deniedIAM role missing permissionsAdd DynamoDB permissions to task role
S3 access deniedIAM role missing permissionsAdd 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

Other materials this week