安装
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill aws-cloudformation-task-ecs-deploy-gh
复制
AWS CloudFormation Task ECS Deploy with GitHub Actions
Comprehensive skill for deploying ECS containers using GitHub Actions CI/CD pipelines with CloudFormation infrastructure management.
Overview
Deploy containerized applications to Amazon ECS using GitHub Actions workflows. This skill covers the complete deployment pipeline: authentication with AWS (OIDC recommended), building Docker images, pushing to Amazon ECR, updating task definitions, and deploying ECS services. Integrate with CloudFormation for infrastructure-as-code management and implement production-grade deployment strategies.
When to Use
Use this skill when:
Deploying Docker containers to Amazon ECS
Setting up GitHub Actions CI/CD pipelines for AWS
Configuring AWS authentication for GitHub Actions (OIDC or IAM keys)
Building and pushing Docker images to Amazon ECR
Updating ECS task definitions dynamically
Implementing blue/green or rolling deployments
Managing CloudFormation stacks from CI/CD
Setting up multi-environment deployments (dev/staging/prod)
Configuring private ECR repositories with image scanning
Automating container deployment with proper security practices
Trigger phrases:
"Deploy to ECS with GitHub Actions"
"Set up CI/CD for ECS containers"
"Configure GitHub Actions for AWS deployment"
"Build and push Docker image to ECR"
"Update ECS task definition from CI/CD"
"Implement blue/green deployment for ECS"
"Deploy CloudFormation stack from GitHub Actions"
Quick Start
Basic ECS Deployment Workflow
name
:
Deploy to ECS
on
:
push
:
branches
:
[
main
]
jobs
:
deploy
:
runs-on
:
ubuntu
-
latest
permissions
:
id-token
:
write
contents
:
read
steps
:
-
name
:
Checkout
uses
:
actions/checkout@v4
-
name
:
Configure AWS credentials
uses
:
aws
-
actions/configure
-
aws
-
credentials@v4
with
:
role-to-assume
:
arn
:
aws
:
iam
:
:
123456789012
:
role/github
-
actions
-
ecs
-
role
aws-region
:
us
-
east
-
1
-
name
:
Login to ECR
uses
:
aws
-
actions/amazon
-
ecr
-
login@v2
-
name
:
Build and push image
env
:
ECR_REGISTRY
:
$
{
{
steps.login
-
ecr.outputs.registry
}
}
ECR_REPOSITORY
:
my
-
app
IMAGE_TAG
:
$
{
{
github.sha
}
}
run
:
|
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
-
name
:
Update task definition
uses
:
aws
-
actions/amazon
-
ecs
-
render
-
task
-
definition@v1
id
:
render
-
task
with
:
task-definition
:
task
-
definition.json
container-name
:
my
-
app
image
:
$
{
{
steps.login
-
ecr.outputs.registry
}
}
/my
-
app
:
$
{
{
github.sha
}
}
-
name
:
Deploy to ECS
uses
:
aws
-
actions/amazon
-
ecs
-
deploy
-
task
-
definition@v1
with
:
task-definition
:
$
{
{
steps.render
-
task.outputs.task
-
definition
}
}
service
:
my
-
service
cluster
:
my
-
cluster
wait-for-service-stability
:
true
Authentication Methods
OIDC Authentication (Recommended)
OpenID Connect (OIDC) provides secure, passwordless authentication between GitHub Actions and AWS.
Prerequisites:
Create IAM role with trust policy for GitHub:
Type
:
AWS
:
:
IAM
:
:
Role
Properties
:
RoleName
:
github
-
actions
-
ecs
-
role
AssumeRolePolicyDocument
:
Version
:
'2012-10-17'
Statement
:
-
Effect
:
Allow
Principal
:
Federated
:
!Sub
'arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com'
Action
:
sts
:
AssumeRoleWithWebIdentity
Condition
:
StringEquals
:
token.actions.githubusercontent.com:aud
:
sts.amazonaws.com
StringLike
:
token.actions.githubusercontent.com:sub
:
repo
:
my
-
org/my
-
repo
:
*
ManagedPolicyArns
:
-
arn
:
aws
:
iam
:
:
aws
:
policy/AmazonECS_FullAccess
-
arn
:
aws
:
iam
:
:
aws
:
policy/AmazonEC2ContainerRegistryFullAccess
Configure GitHub Actions workflow:
-
name
:
Configure AWS credentials
uses
:
aws
-
actions/configure
-
aws
-
credentials@v4
with
:
role-to-assume
:
arn
:
aws
:
iam
:
:
123456789012
:
role/github
-
actions
-
ecs
-
role
aws-region
:
us
-
east
-
1
IAM Key Authentication (Legacy)
-
name
:
Configure AWS credentials
uses
:
aws
-
actions/configure
-
aws
-
credentials@v4
with
:
aws-access-key-id
:
$
{
{
secrets.AWS_ACCESS_KEY_ID
}
}
aws-secret-access-key
:
$
{
{
secrets.AWS_SECRET_ACCESS_KEY
}
}
aws-region
:
us
-
east
-
1
Store credentials in GitHub repository secrets (Settings → Secrets and variables → Actions).
Build and Push to ECR
ECR Repository CloudFormation Template
ECRRepository
:
Type
:
AWS
:
:
ECR
:
:
Repository
Properties
:
RepositoryName
:
my
-
app
ImageScanningConfiguration
:
ScanOnPush
:
true
ImageTagMutability
:
IMMUTABLE
LifecyclePolicy
:
LifecyclePolicyText
:
|
{
"rules": [
{
"rulePriority": 1,
"description": "Keep last 30 images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}
Build and Push Step
-
name
:
Login to ECR
id
:
login
-
ecr
uses
:
aws
-
actions/amazon
-
ecr
-
login@v2
-
name
:
Set up Docker Buildx
uses
:
docker/setup
-
buildx
-
action@v3
-
name
:
Build and push
uses
:
docker/build
-
push
-
action@v5
with
:
context
:
.
push
:
true
tags
:
|
${{ steps.login-ecr.outputs.registry }}/my-app:${{ github.sha }}
${{ steps.login-ecr.outputs.registry }}/my-app:latest
cache-from
:
type=gha
cache-to
:
type=gha
,
mode=max
build-args
:
|
BUILD_DATE=${{ github.event.head_commit.timestamp }}
VERSION=${{ github.sha }}
Task Definition Management
Basic Task Definition
task-definition.json:
{
"family"
:
"my-app-task"
,
"networkMode"
:
"awsvpc"
,
"requiresCompatibilities"
:
[
"FARGATE"
]
,
"cpu"
:
"256"
,
"memory"
:
"512"
,
"executionRoleArn"
:
"arn:aws:iam::123456789012:role/ecsTaskExecutionRole"
,
"taskRoleArn"
:
"arn:aws:iam::123456789012:role/ecsTaskRole"
,
"containerDefinitions"
:
[
{
"name"
:
"my-app"
,
"image"
:
"PLACEHOLDER_IMAGE"
,
"portMappings"
:
[
{
"containerPort"
:
8080
,
"protocol"
:
"tcp"
}
]
,
"environment"
:
[
{
"name"
:
"ENVIRONMENT"
,
"value"
:
"production"
}
]
,
"secrets"
:
[
{
"name"
:
"DB_PASSWORD"
,
"valueFrom"
:
"arn:aws:secretsmanager:us-east-1:123456789012:secret:my-app/db-password"
}
]
,
"logConfiguration"
:
{
"logDriver"
:
"awslogs"
,
"options"
:
{
"awslogs-group"
:
"/ecs/my-app"
,
"awslogs-region"
:
"us-east-1"
,
"awslogs-stream-prefix"
:
"ecs"
,
"awslogs-create-group"
:
"true"
}
}
}
]
}
Dynamic Task Definition Update
-
name
:
Render task definition
uses
:
aws
-
actions/amazon
-
ecs
-
render
-
task
-
definition@v1
id
:
render
-
task
with
:
task-definition
:
task
-
definition.json
container-name
:
my
-
app
image
:
$
{
{
steps.login
-
ecr.outputs.registry
}
}
/my
-
app
:
$
{
{
github.sha
}
}
-
name
:
Deploy task definition
uses
:
aws
-
actions/amazon
-
ecs
-
deploy
-
task
-
definition@v1
with
:
task-definition
:
$
{
{
steps.render
-
task.outputs.task
-
definition
}
}
service
:
my
-
service
cluster
:
my
-
cluster
wait-for-service-stability
:
true
deploy_timeout
:
30 minutes
ECS Deployment Strategies
Rolling Deployment (Default)
-
name
:
Deploy to ECS (Rolling)
uses
:
aws
-
actions/amazon
-
ecs
-
deploy
-
task
-
definition@v1
with
:
task-definition
:
$
{
{
steps.render
-
task.outputs.task
-
definition
}
}
service
:
my
-
service
cluster
:
my
-
cluster
wait-for-service-stability
:
true
CloudFormation Service Configuration:
ECSService
:
Type
:
AWS
:
:
ECS
:
:
Service
Properties
:
ServiceName
:
my
-
service
Cluster
:
!Ref
ECSCluster
TaskDefinition
:
!Ref
TaskDefinition
DeploymentConfiguration
:
MaximumPercent
:
200
MinimumHealthyPercent
:
100
DeploymentCircuitBreaker
:
Enable
:
true
Rollback
:
true
HealthCheckGracePeriodSeconds
:
60
EnableECSManagedTags
:
true
PropagateTags
:
SERVICE
Blue/Green Deployment with CodeDeploy
-
name
:
Deploy to ECS (Blue/Green)
uses
:
aws
-
actions/amazon
-
ecs
-
deploy
-
task
-
definition@v1
with
:
task-definition
:
$
{
{
steps.render
-
task.outputs.task
-
definition
}
}
service
:
my
-
service
cluster
:
my
-
cluster
codedeploy-appspec
:
appspec.yaml
codedeploy-application
:
my
-
app
codedeploy-deployment-group
:
my
-
deployment
-
group
wait-for-service-stability
:
true
appspec.yaml:
version
:
0.0
Resources
:
-
TargetService
:
Type
:
AWS
:
:
ECS
:
:
Service
Properties
:
TaskDefinition
:
<TASK_DEFINITION
>
LoadBalancerInfo
:
ContainerName
:
my
-
app
ContainerPort
:
8080
PlatformVersion
:
"1.4.0"
CloudFormation CodeDeploy Configuration:
CodeDeployApplication
:
Type
:
AWS
:
:
CodeDeploy
:
:
Application
Properties
:
ApplicationName
:
my
-
app
ComputePlatform
:
ECS
CodeDeployDeploymentGroup
:
Type
:
AWS
:
:
CodeDeploy
:
:
DeploymentGroup
Properties
:
ApplicationName
:
!Ref
CodeDeployApplication
DeploymentGroupName
:
my
-
deployment
-
group
ServiceRoleArn
:
!Ref
CodeDeployServiceRole
DeploymentConfigName
:
CodeDeployDefault.ECSAllAtOnce
DeploymentStyle
:
DeploymentType
:
BLUE_GREEN
DeploymentOption
:
WITH_TRAFFIC_CONTROL
AutoRollbackConfiguration
:
Enabled
:
true
Events
:
-
DEPLOYMENT_FAILURE
-
DEPLOYMENT_STOP_ON_ALARM
-
DEPLOYMENT_STOP_ON_REQUEST
AlarmConfiguration
:
Alarms
:
-
!Ref
CPUPercentageAlarm
-
!Ref
MemoryPercentageAlarm
BlueGreenDeploymentConfiguration
:
TerminateBlueInstancesOnDeploymentSuccess
:
Action
:
TERMINATE
WaitTimeInMinutes
:
5
DeploymentReadyOption
:
ActionOnTimeout
:
CONTINUE_DEPLOYMENT
WaitTimeInMinutes
:
0
LoadBalancerInfo
:
TargetGroupPairInfoList
:
-
TargetGroups
:
-
Ref
:
BlueTargetGroup
-
Ref
:
GreenTargetGroup
ProdTrafficRoute
:
ListenerArns
:
-
!Ref
ProductionListener
CloudFormation Integration
Update Stack from GitHub Actions
-
name
:
Deploy CloudFormation stack
run
:
|
aws cloudformation deploy \
--template-file infrastructure/ecs-stack.yaml \
--stack-name my-app-ecs \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
Environment=production \
DesiredCount=2 \
CPU=256 \
Memory=512 \
ImageUrl=${{ steps.login-ecr.outputs.registry }}/my-app:${{ github.sha }}
CloudFormation Stack with ECS Resources
ecs-stack.yaml:
AWSTemplateFormatVersion
:
'2010-09-09'
Description
:
ECS Fargate Service with CloudFormation
Parameters
:
Environment
:
Type
:
String
AllowedValues
:
[
dev
,
staging
,
prod
]
DesiredCount
:
Type
:
Number
Default
:
2
CPU
:
Type
:
String
Default
:
'256'
Memory
:
Type
:
String
Default
:
'512'
ImageUrl
:
Type
:
String
Resources
:
ECSCluster
:
Type
:
AWS
:
:
ECS
:
:
Cluster
Properties
:
ClusterName
:
!Sub
'${Environment}-cluster'
ClusterSettings
:
-
Name
:
containerInsights
Value
:
enabled
TaskDefinition
:
Type
:
AWS
:
:
ECS
:
:
TaskDefinition
Properties
:
Family
:
!Sub
'${Environment}-task'
Cpu
:
!Ref
CPU
Memory
:
!Ref
Memory
NetworkMode
:
awsvpc
RequiresCompatibilities
:
-
FARGATE
ExecutionRoleArn
:
!GetAtt
TaskExecutionRole.Arn
TaskRoleArn
:
!GetAtt
TaskRole.Arn
ContainerDefinitions
:
-
Name
:
my
-
app
Image
:
!Ref
ImageUrl
PortMappings
:
-
ContainerPort
:
8080
LogConfiguration
:
LogDriver
:
awslogs
Options
:
awslogs-group
:
!Ref
LogGroup
awslogs-region
:
!Ref
AWS
:
:
Region
awslogs-stream-prefix
:
ecs
ECSService
:
Type
:
AWS
:
:
ECS
:
:
Service
DependsOn
:
LoadBalancerListener
Properties
:
ServiceName
:
!Sub
'${Environment}-service'
Cluster
:
!Ref
ECSCluster
TaskDefinition
:
!Ref
TaskDefinition
DesiredCount
:
!Ref
DesiredCount
LaunchType
:
FARGATE
NetworkConfiguration
:
AwsvpcConfiguration
:
Subnets
:
-
!Ref
PrivateSubnetA
-
!Ref
PrivateSubnetB
SecurityGroups
:
-
!Ref
ContainerSecurityGroup
AssignPublicIp
:
DISABLED
LoadBalancers
:
-
ContainerName
:
my
-
app
ContainerPort
:
8080
TargetGroupArn
:
!Ref
TargetGroup
DeploymentConfiguration
:
MaximumPercent
:
200
MinimumHealthyPercent
:
100
DeploymentCircuitBreaker
:
Enable
:
true
Rollback
:
true
HealthCheckGracePeriodSeconds
:
60
Outputs
:
ServiceURL
:
Description
:
Service URL
Value
:
!Sub
'http://${LoadBalancer.DNSName}'
Stack Outputs for Cross-Stack References
Outputs
:
ClusterName
:
Description
:
ECS Cluster Name
Value
:
!Ref
ECSCluster
Export
:
Name
:
!Sub
'${AWS::StackName}-ClusterName'
ServiceName
:
Description
:
ECS Service Name
Value
:
!Ref
ECSService
Export
:
Name
:
!Sub
'${AWS::StackName}-ServiceName'
TaskDefinitionArn
:
Description
:
Task Definition ARN
Value
:
!Ref
TaskDefinition
Export
:
Name
:
!Sub
'${AWS::StackName}-TaskDefinitionArn'
Best Practices
Security
Use OIDC authentication
instead of long-lived IAM keys
Implement least privilege IAM roles
with specific permissions
Enable ECR image scanning
on push
Use AWS Secrets Manager
for sensitive data
Encrypt ECR repositories
with KMS
VPC endpoints
for ECR and ECS without internet gateway
Security groups
restrict access to minimum required
IAM Role Permissions
ECSDeployRole
:
Type
:
AWS
:
:
IAM
:
:
Role
Properties
:
AssumeRolePolicyDocument
:
Version
:
'2012-10-17'
Statement
:
-
Effect
:
Allow
Principal
:
Federated
:
!Sub
'arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com'
Action
:
sts
:
AssumeRoleWithWebIdentity
Condition
:
StringEquals
:
token.actions.githubusercontent.com:aud
:
sts.amazonaws.com
StringLike
:
token.actions.githubusercontent.com:sub
:
repo
:
$
{
GitHubOrg
}
/$
{
GitHubRepo
}
:
*
Policies
:
-
PolicyName
:
ECSDeployPolicy
PolicyDocument
:
Version
:
'2012-10-17'
Statement
:
-
Effect
:
Allow
Action
:
-
ecs
:
DescribeServices
-
ecs
:
DescribeTaskDefinition
-
ecs
:
DescribeTasks
-
ecs
:
ListTasks
-
ecs
:
RegisterTaskDefinition
-
ecs
:
UpdateService
Resource
:
!Sub
'arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:*'
-
Effect
:
Allow
Action
:
-
ecr
:
GetAuthorizationToken
-
ecr
:
BatchCheckLayerAvailability
-
ecr
:
GetDownloadUrlForLayer
-
ecr
:
GetRepositoryPolicy
-
ecr
:
DescribeRepositories
-
ecr
:
ListImages
-
ecr
:
DescribeImages
-
ecr
:
BatchGetImage
-
ecr
:
InitiateLayerUpload
-
ecr
:
UploadLayerPart
-
ecr
:
CompleteLayerUpload
-
ecr
:
PutImage
Resource
:
!Sub
'arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepositoryName}'
-
Effect
:
Allow
Action
:
-
cloudformation
:
DescribeStacks
-
cloudformation
:
CreateStack
-
cloudformation
:
UpdateStack
-
cloudformation
:
DescribeStackEvents
Resource
:
!Sub
'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${CloudFormationStackName}/*'
Performance
Docker layer caching
with GitHub Actions cache
Multi-stage builds
to minimize image size
Parallel deployments
across multiple environments
Fargate Spot
for cost savings on non-critical workloads
CloudWatch Logs
with appropriate retention policies
Cost Optimization
ECR lifecycle policies
to clean up old images
Fargate Spot
instances for development/testing
Right-sized task CPU and memory
Auto-scaling
based on metrics
Scheduled scaling
for predictable traffic patterns
Multi-Environment Deployments
name
:
Deploy to ECS
on
:
push
:
branches
:
[
main
,
staging
,
develop
]
jobs
:
deploy
:
runs-on
:
ubuntu
-
latest
permissions
:
id-token
:
write
contents
:
read
strategy
:
matrix
:
environment
:
[
dev
,
staging
,
prod
]
steps
:
-
name
:
Configure AWS credentials
uses
:
aws
-
actions/configure
-
aws
-
credentials@v4
with
:
role-to-assume
:
arn
:
aws
:
iam
:
:
123456789012
:
role/github
-
actions
-
ecs
-
$
{
{
matrix.environment
}
}
aws-region
:
us
-
east
-
1
-
name
:
Deploy to $
{
{
matrix.environment
}
}
run
:
|
aws cloudformation deploy \
--template-file infrastructure/ecs-stack.yaml \
--stack-name my-app-${{ matrix.environment }} \
--parameter-overrides \
Environment=${{ matrix.environment }} \
ImageUrl=${{ steps.build-image.outputs.image-url }}
Monitoring and Observability
CloudWatch Container Insights
for ECS metrics
Application logs
centralized in CloudWatch Logs
Health checks
with proper grace periods
CloudWatch Alarms
for deployment failures
X-Ray tracing
for distributed tracing
Further Reading
Reference Documentation
- Detailed technical reference for GitHub Actions syntax, OIDC configuration, ECR operations, task definitions, and CloudFormation integration
Production Examples
- Complete, production-ready workflows including basic deployments, multi-environment setups, blue/green deployments, private ECR with scanning, CloudFormation stack updates, and full CI/CD pipelines with testing
Key Concepts
GitHub Actions
Automate workflows from GitHub repository events
OIDC Authentication
Secure, tokenless authentication between GitHub and AWS
ECR
Amazon Elastic Container Registry for Docker image storage
ECS
Amazon Elastic Container Service for container orchestration
Fargate
Serverless compute engine for ECS without managing servers
Task Definition
Blueprint for ECS containers (similar to Pod spec in Kubernetes)
Service
Long-running ECS service with load balancing and auto-scaling
CloudFormation
Infrastructure as Code for AWS resource management
Blue/Green Deployment
Zero-downtime deployment strategy with CodeDeploy
Common Troubleshooting
Authentication failures:
Verify OIDC trust relationship matches GitHub organization/repository
Check IAM role has proper permissions for ECR and ECS
Ensure GitHub Actions repository has
id-token: write
permission
Deployment failures:
Check CloudWatch Logs for application errors
Verify task definition matches service requirements
Ensure sufficient CPU/memory in Fargate cluster
Review health check configuration
ECR push failures:
Verify repository exists and permissions are correct
Check image tag format and registry URL
Ensure Docker daemon is running in GitHub Actions runner
Verify image size doesn't exceed ECR limits
CloudFormation rollback:
Review stack events in AWS Console
Check parameter values match resource constraints
Verify IAM role has
cloudformation:UpdateStack
permission
Enable termination protection for production stacks
← 返回排行榜