Task Definition, IAM, and CloudWatch Logs¶
Goal
Capture all dependencies around Task Definitions, IAM roles, and CloudWatch logging.
Avoid “task immediately stopped” failures by setting up IAM and log groups correctly.
Execution role (ecsTaskExecutionRole)¶
Execution role responsibilities
Execution role is used by ECS itself, not by the application code.
Responsibilities:
- Pull images from ECR.
- Create or use a CloudWatch log group.
- Create log streams.
- Write container logs to CloudWatch.
Create the execution role:
aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
Attach the managed policy:
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Confirm the role:
aws iam get-role --role-name ecsTaskExecutionRole
Log configuration in Task Definition¶
awslogs driver fields
Use the awslogs driver with three required options: awslogs-group, awslogs-region, awslogs-stream-prefix.
Example container definition snippet:
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/portfolio",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "portfolio"
}
}
Understand behaviour:
awslogs-grouppoints to a CloudWatch Logs group.awslogs-regionmust match ECS region.awslogs-stream-prefixprefixes log stream names.
If the log group does not exist and the execution role does not have logs:CreateLogGroup, the Task may fail at log initialization and stop immediately.
AmazonECSTaskExecutionRolePolicy limitation
The AWS managed AmazonECSTaskExecutionRolePolicy does not include the logs:CreateLogGroup permission. This is why explicit log group creation is recommended unless manually adding inline policies to the role.
Creating the CloudWatch log group¶
Create a log group explicitly
Create the log group before registering the Task Definition.
REGION=us-east-1
LOG_GROUP="/ecs/portfolio"
aws logs create-log-group \
--log-group-name "$LOG_GROUP" \
--region "$REGION" || true
aws logs describe-log-groups \
--log-group-name-prefix "$LOG_GROUP" \
--region "$REGION"
Prefer explicit creation during learning:
- Avoid depending on
awslogs-create-group=trueand implicit log group creation. - Keep control over naming and retention settings.
Task Definition minimal fields¶
Minimal Task Definition content
Start with the minimal valid Task Definition and extend as needed.
Minimal fields for Fargate:
familyrequiresCompatibilities: ["FARGATE"]networkMode: "awsvpc"cpu,memoryexecutionRoleArn- one or more
containerDefinitions: nameimageportMappingslogConfiguration
Example:
AWS_ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
REGION=us-east-1
EXEC_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT}:role/ecsTaskExecutionRole"
cat > portfolio-taskdef.json <<EOF
{
"family": "portfolio-task",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512",
"executionRoleArn": "${EXEC_ROLE_ARN}",
"containerDefinitions": [
{
"name": "portfolio",
"image": "ghcr.io/ibtisam-iq/ibtisam-iq:latest",
"portMappings": [
{ "containerPort": 8080, "protocol": "tcp" }
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/portfolio",
"awslogs-region": "${REGION}",
"awslogs-stream-prefix": "portfolio"
}
}
}
]
}
EOF
aws ecs register-task-definition \
--cli-input-json file://portfolio-taskdef.json \
--region "$REGION"
Network mode inside Task Definition¶
Network mode is not VPC selection
networkMode configures how networking works for the Task, but not which VPC or subnet it uses.
For Fargate:
- Set
networkModetoawsvpc. - Treat this as enabling “each Task gets its own ENI and IP address”.
Actual VPC, subnet, and security groups are only chosen later when running the Task or creating the Service.