Amazon Elastic Container Service (ECS) is AWS’s container orchestration service. Think of it as a system that manages where and how your Docker containers run in the cloud.
Launch Type | You Manage | Best For | Common Use Cases |
---|---|---|---|
AWS Fargate | Nothing - fully managed | Teams focused on apps | • Microservices • Web applications • API backends |
EC2 | EC2 instances & capacity | Infrastructure control | • Legacy apps • GPU workloads • Cost optimization |
AWS Fargate (Serverless)
Amazon EC2
Think of this as the blueprint for your application. It includes:
Example Task Definition components:
{
"family": "web-app",
"containerDefinitions": [
{
"name": "web", // Container name
"image": "nginx:latest", // Docker image
"cpu": 256, // CPU units
"memory": 512, // Memory in MB
"portMappings": [
{
// Port configurations
"containerPort": 80
}
]
}
]
}
Think of it as a restaurant manager who:
graph TD
A[ECS Cluster] --> B[ECS Service]
B --> C[Task Definition]
C --> D[Container 1]
C --> E[Container 2]
C --> F[Container N]
In this section, we will:
rent-a-room-cluster
# Check if the ECS service-linked role already exists
if ! aws iam get-role --role-name AWSServiceRoleForECS &> /dev/null; then
echo "Creating ECS service-linked role..."
aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com
# Wait for role to propagate
echo "Waiting for role to propagate..."
sleep 20
else
echo "✅ ECS service-linked role already exists"
fi
# Create the ECS cluster
echo "Creating ECS cluster..."
aws ecs create-cluster --cluster-name rent-a-room-cluster
In ECS console, go to Task Definitions
Click Create new Task Definition
Configure settings: Family:
rent-a-room-task
Launch type: FARGATE
Operating system/Architecture: Linux/ARM64 (⚠️ Make sure to swap to Linux/ARM64)
Task CPU: 1 vCPU
Task memory: 3GB
Add container( ⚠️ Be sure to replace the image prefix with your DockerHub Username below):
Container name: rent-a-room
Image: YOUR_DOCKERHUB_USERNAME/rent-a-room:latest
Note: The rest of the options will remain to the default values
Click Create
Save this as task-definition.json
:
cat << EOF > task-definition.json
{
"family": "rent-a-room-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"runtimePlatform": {
"cpuArchitecture": "ARM64",
"operatingSystemFamily": "LINUX"
},
"containerDefinitions": [{
"name": "rent-a-room",
"image": "${DOCKER_USERNAME}/rent-a-room:latest",
"portMappings": [{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}]
}]
}
EOF
Then run:
aws ecs register-task-definition --cli-input-json file://task-definition.json
Task Definition family: rent-a-room-task
Service name (⚠️ System with automatically add task-random string to end. Delete the entire text and paste “rent-a-room-service”):
rent-a-room-service
Launch type: FARGATE
Platform Version: LATEST
Service Type: Replica
Desired Tasks: 1
VPC: Default VPC
Subnets: Select all available (No need to change this)
Security group: Create new
Security Group Name:
ecs-rent-a-room-sg
Type: Select `HTTP`
Port Range: 80
Source: Custom
Values: Your IP Address/32 (To obtain your Personal IP address, Navigate here, you will need to add /32 to the end of the value you see on the webpage. ex. 123.123.123.123/32) ⚠️ If this addess is incorrect, you will not be able to access the ECS Service!
# Get default VPC ID
VPC_ID=$(aws ec2 describe-vpcs \
--filters Name=isDefault,Values=true \
--query 'Vpcs[0].VpcId' \
--output text)
# Get first subnet ID from default VPC
SUBNET_ID=$(aws ec2 describe-subnets \
--filters Name=vpc-id,Values=$VPC_ID \
--query 'Subnets[0].SubnetId' \
--output text)
# Create security group
SECURITY_GROUP_ID=$(aws ec2 create-security-group \
--group-name ecs-rent-a-room-sg \
--description "Security group for Rent-A-Room ECS service" \
--vpc-id $VPC_ID \
--query 'GroupId' \
--output text)
# Add inbound rule for port 80
aws ec2 authorize-security-group-ingress \
--group-id $SECURITY_GROUP_ID \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
# Create the ECS service with dynamic values
aws ecs create-service \
--cluster rent-a-room-cluster \
--service-name rent-a-room-service \
--task-definition rent-a-room-task \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET_ID],securityGroups=[$SECURITY_GROUP_ID],assignPublicIp=ENABLED}"
http://[PUBLIC_IP]
⚠️ Please be sure to connect via http and not https. If you still cannot connect,
# Wait for service to be stable
echo "Waiting for ECS service to be stable..."
aws ecs wait services-stable \
--cluster rent-a-room-cluster \
--services rent-a-room-service
# Get the task ARN (with verification)
echo "Getting task information..."
TASK_ARN=$(aws ecs list-tasks \
--cluster rent-a-room-cluster \
--service-name rent-a-room-service \
--query 'taskArns[0]' \
--output text)
if [ "$TASK_ARN" == "None" ] || [ -z "$TASK_ARN" ]; then
echo "No tasks found. Waiting for tasks to start..."
sleep 30 # Wait for tasks to start
TASK_ARN=$(aws ecs list-tasks \
--cluster rent-a-room-cluster \
--service-name rent-a-room-service \
--query 'taskArns[0]' \
--output text)
fi
echo "Task ARN: $TASK_ARN"
# Wait for task to be running
echo "Waiting for task to be running..."
aws ecs wait tasks-running \
--cluster rent-a-room-cluster \
--tasks $TASK_ARN
# Get the ENI ID attached to the task
echo "Getting network interface ID..."
ENI_ID=$(aws ecs describe-tasks \
--cluster rent-a-room-cluster \
--tasks $TASK_ARN \
--query 'tasks[0].attachments[0].details[?name==`networkInterfaceId`].value' \
--output text)
echo "ENI ID: $ENI_ID"
# Get the public IP
if [ ! -z "$ENI_ID" ]; then
echo "Getting public IP..."
PUBLIC_IP=$(aws ec2 describe-network-interfaces \
--network-interface-ids $ENI_ID \
--query 'NetworkInterfaces[0].Association.PublicIp' \
--output text)
echo "Your application is available at: http://$PUBLIC_IP:80"
else
echo "Could not get network interface ID. Task might still be starting."
fi
Monitor your application using:
Concept | Understanding |
---|---|
ECS Cluster | The foundation that hosts your containers - like a virtual data center |
Launch Types | Fargate (serverless) vs EC2 (server-based) - choose based on your needs |
Task Definition | The blueprint that defines how your container should run |
ECS Service | The manager that maintains your desired container state |
Architecture | Understanding how all components work together for container orchestration |
Now that you have:
✨ Continue to CI/CD Pipeline Setup ▶️