DEV Community

Yash
Yash

Posted on

AWS ECR + GitHub Actions: the complete container CI/CD pipeline

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" } }
  ]})
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

👉 step2dev.com

What ECS deployment issue has cost you the most debugging time?

Top comments (0)