Saturday, 22 February 2025

End-to-End Guide: Automating Docker Image Deployment to AWS ECR, ECS, and EKS


In this comprehensive guide, you’ll learn how to automate the process of building, pushing, and deploying Docker images to AWS ECR, ECS, and EKS. We’ll cover CI/CD pipelines using AWS CodePipeline and GitHub Actions, advanced security practices, Infrastructure as Code (IaC), and monitoring. By the end, you’ll have a production-ready workflow that ensures scalability, security, and efficiency.

Table of Contents

  1. Automate with AWS CodePipeline

    • 1.1 Set Up CodeCommit and CodeBuild
    • 1.2 Secure CodeBuild with IAM Roles
    • 1.3 Optimize Builds with Caching
    • 1.4 Deploy to ECS/EKS via CodePipeline
  2. Automate with GitHub Actions

    • 2.1 Dynamic Image Tagging
    • 2.2 Secure AWS Authentication with OIDC
    • 2.3 Add Testing to CI/CD
  3. Deploy to Amazon ECS

    • 3.1 Task Execution Roles for ECR Access
    • 3.2 Configure Load Balancers and Health Checks
  4. Deploy to Amazon EKS

    • 4.1 ECR Permissions for Worker Nodes
    • 4.2 Kubernetes Secrets for Private ECR Repos
    • 4.3 Ingress and Advanced Routing
  5. Infrastructure as Code (IaC)

    • 5.1 Define ECS/EKS Resources with CloudFormation
    • 5.2 Terraform Example for ECR and EKS
  6. Monitoring and Logging

    • 6.1 Integrate Amazon CloudWatch

1. Automate with AWS CodePipeline

1.1 Set Up CodeCommit and CodeBuild

  1. Create a CodeCommit Repository:

    • Navigate to AWS CodeCommit > Create repository.
    • Clone the repository and push your code:
      git clone codecommit::<region>://my-repo
      cd my-repo
      git add .
      git commit -m "Initial commit"
      git push origin main
      
  2. Create a CodeBuild Project:

    • Use the AWS Management Console to create a project with:
      • Source Provider: CodeCommit.
      • Environment Image: Managed Docker image (e.g., aws/codebuild/standard:7.0).
      • Service Role: Let CodeBuild create a default role (we’ll modify this later).

1.2 Secure CodeBuild with IAM Roles

Instead of hardcoding credentials, attach an IAM role to CodeBuild with ECR permissions:

  1. Go to IAM > Roles > Create Role.
  2. Select AWS Service > CodeBuild.
  3. Attach the following policy:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ecr:GetAuthorizationToken",
            "ecr:BatchCheckLayerAvailability",
            "ecr:PutImage"
          ],
          "Resource": "*"
        }
      ]
    }
    
  4. Attach this role to your CodeBuild project under Build > Environment > Service Role.

1.3 Optimize Builds with Caching

Add caching to your buildspec.yml to speed up builds:

version: 0.2
phases:
  install:
    runtime-versions:
      docker: 20
  pre_build:
    commands:
      - echo "Logging in to ECR..."
      - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_URI
  build:
    commands:
      - docker build -t $ECR_URI:latest .
  post_build:
    commands:
      - docker push $ECR_URI:latest
cache:
  paths:
    - '/root/.cache/**/*'  # Cache dependencies

1.4 Deploy to ECS/EKS via CodePipeline

  1. Add a Deploy Stage:
    • For ECS: Use AWS CloudFormation to deploy a task definition.
    • For EKS: Use kubectl in a CodeBuild phase to apply Kubernetes manifests.

2. Automate with GitHub Actions

2.1 Dynamic Image Tagging

Tag images with the Git commit SHA for traceability:

- name: Build Docker Image
  run: |
    docker build -t ${{ secrets.ECR_URI }}:${{ github.sha }} .
    docker push ${{ secrets.ECR_URI }}:${{ github.sha }}

2.2 Secure AWS Authentication with OIDC

Replace long-lived credentials with OIDC for enhanced security:

  1. Configure OIDC in AWS IAM:

    • Create an IAM Identity Provider for GitHub.
    • Attach a policy allowing ecr:PutImage to the GitHub OIDC role.
  2. Update the GitHub Actions Workflow:

    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v3
      with:
        role-to-assume: arn:aws:iam::<account-id>:role/github-actions-role
        aws-region: <region>
    

2.3 Add Testing to CI/CD

Include a testing phase in your workflow:

- name: Run Unit Tests
  run: |
    npm install
    npm test  # Example for Node.js

3. Deploy to Amazon ECS

3.1 Task Execution Roles for ECR Access

ECS tasks need permissions to pull images from ECR:

  1. Create an IAM role with the AmazonECSTaskExecutionRolePolicy.
  2. Attach an inline policy for ECR access:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "ecr:GetAuthorizationToken",
          "Resource": "*"
        }
      ]
    }
    

3.2 Configure Load Balancers and Health Checks

  1. Create an Application Load Balancer (ALB):

    • In the ECS service wizard, select Application Load Balancer.
    • Configure listener ports and target groups.
  2. Add Health Checks:

    "healthCheck": {
      "command": ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"],
      "interval": 30,
      "timeout": 5,
      "retries": 3
    }
    

4. Deploy to Amazon EKS

4.1 ECR Permissions for Worker Nodes

Ensure EKS worker nodes can pull images from ECR:

  1. Attach the AmazonEC2ContainerRegistryReadOnly policy to the worker node IAM role.

4.2 Kubernetes Secrets for Private ECR Repos

Create a Kubernetes secret to authenticate with ECR:

kubectl create secret docker-registry ecr-secret \
  --docker-server=<account-id>.dkr.ecr.<region>.amazonaws.com \
  --docker-username=AWS \
  --docker-password=$(aws ecr get-login-password --region <region>)

Reference the secret in your deployment:

spec:
  containers:
  - name: my-app
    image: <ecr-image-uri>
  imagePullSecrets:
  - name: ecr-secret

4.3 Ingress and Advanced Routing

Use an Ingress resource to route traffic:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80

5. Infrastructure as Code (IaC)

5.1 Define ECS Resources with CloudFormation

Example CloudFormation template for ECS:

Resources:
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: my-ecs-cluster

  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: my-task
      Cpu: 256
      Memory: 512
      NetworkMode: awsvpc
      RequiresCompatibilities: [FARGATE]
      ExecutionRoleArn: arn:aws:iam::<account-id>:role/ecs-task-execution-role
      ContainerDefinitions:
        - Name: my-container
          Image: <ecr-image-uri>
          PortMappings:
            - ContainerPort: 80

5.2 Terraform Example for EKS

Define EKS and ECR resources using Terraform:

resource "aws_ecr_repository" "my_repo" {
  name = "my-app-repo"
}

resource "aws_eks_cluster" "my_cluster" {
  name     = "my-eks-cluster"
  role_arn = aws_iam_role.eks_cluster.arn
  vpc_config {
    subnet_ids = [subnet-1, subnet-2]
  }
}

6. Monitoring and Logging

6.1 Integrate Amazon CloudWatch

  1. ECS Logging:

    • Enable the awslogs driver in your task definition:
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-task",
          "awslogs-region": "<region>"
        }
      }
      
  2. EKS Logging:

    • Enable control plane logging in the EKS cluster settings.
    • Use Fluent Bit to forward logs to CloudWatch:
      kubectl apply -f https://github.com/aws-samples/amazon-cloudwatch-container-insights/blob/main/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
      

By following this guide, you’ve built a robust pipeline to automate Docker image deployment to AWS ECR, ECS, and EKS. Key takeaways include:

  • Security: Use IAM roles and OIDC instead of hardcoded credentials.
  • Efficiency: Optimize builds with caching and dynamic tagging.
  • Scalability: Deploy with ECS Fargate or EKS for serverless orchestration.
  • Observability: Monitor logs and metrics with CloudWatch.
  • IaC: Manage infrastructure using CloudFormation or Terraform.

 

Labels: , ,

0 Comments:

Post a Comment

Note: only a member of this blog may post a comment.

<< Home