AWS ECR + GitHub Actions: the complete container CI/CD pipeline
ECR setup (Terraform)
resource "aws_ecr_repository" "app" {
name = var.service_name
image_scanning_configuration { scan_on_push = true }
encryption_configuration { encryption_type = "AES256" }
}
resource "aws_ecr_lifecycle_policy" "app" {
repository = aws_ecr_repository.app.name
policy = jsonencode({ rules = [
{ rulePriority = 1; selection = { tagStatus = "untagged"
countType = "sinceImagePushed"; countUnit = "days"; countNumber = 1 }
action = { type = "expire" } },
{ rulePriority = 2; selection = { tagStatus = "any"
countType = "imageCountMoreThan"; countNumber = 10 }
action = { type = "expire" } }
]})
}
Complete workflow
name: Build and Deploy
on: { push: { branches: [main] } }
permissions: { id-token: write, contents: read }
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with: { role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}, aws-region: us-east-1 }
- id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- uses: docker/build-push-action@v5
with:
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/my-service:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- run: |
aws ecs describe-task-definition --task-definition my-service --query taskDefinition > task-definition.json
- id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: my-service
image: ${{ steps.login-ecr.outputs.registry }}/my-service:${{ github.sha }}
- uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: my-service; cluster: production
wait-for-service-stability: true
Critical gotchas
-
wait-for-service-stability: true: Without this, workflow succeeds before tasks are actually running -
Tag with SHA: Deterministic and debuggable — not just
:latest -
cache-from: type=gha: Reduces build times 60%+ for large images - Download task definition: Don't store it in the repo — download current and update it
Step2Dev generates this pipeline for every new project.
What ECS deployment issue has cost you the most debugging time?
Top comments (0)