DEV Community

Syed Omair
Syed Omair

Posted on • Edited on

2 1 1 1 1

How to Deploy a Container from GitHub to AWS ECR and ECS through OIDC

Deploying a container from GitHub Actions to AWS Elastic Container Registry (ECR) and AWS Elastic Container Service (ECS) can be done securely using OpenID Connect (OIDC). This method eliminates the need to store long-lived AWS credentials, making your CI/CD pipeline more secure. This guide will walk you through setting up OIDC authentication for GitHub Actions to push Docker images to AWS ECR.

Step 1: Enable OIDC Provider in AWS

  • Sign in to AWS Console and navigate to IAM.
  • Go to Identity providers > Add provider.
  • Select OpenID Connect as the provider type.
  • Enter the Provider URL:
https://token.actions.githubusercontent.com
Enter fullscreen mode Exit fullscreen mode
  • Click Get thumbprint (AWS will auto-populate this).
  • Under Audience, enter:
https://github.com
Enter fullscreen mode Exit fullscreen mode
  • Click Add provider.

Step 2: Create an IAM Role for GitHub Actions

  • In the AWS Console, go to IAM > Roles > Create Role.
  • Select Web identity as the trusted entity type.
  • Choose the OIDC provider you just created.
  • Under 'Audience' enter https://github.com
  • Under 'GitHub organization' enter your .
  • Click Next.
  • Under 'Name' enter github-role
  • Click Create

Step 3: Attach Policies for ECR and ECS Access

  • create a custom policy for more control
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload",
                "ecr:DescribeRepositories",
                "ecr:CreateRepository",
                "ecr:ListImages",
                "ecr:BatchDeleteImage"
            ],
            "Resource": "*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode
  • Click Next, then give the policy a name (e.g., GitHubActionsECR).
  • Click Create policy. Add another policy name githubECS for ECS Update
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:UpdateService",
                "ecs:DescribeServices"
            ],
            "Resource": [
                "<ARN of ECS service 1",
                "<ARN of ECS service 2",
                "<ARN of ECS service n"
            ]
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Image description

Step 4: Update Trust PolicyModify the trust policy to allow GitHub Actions to assume this role:

  • Go to IAM > Roles > Select your role (GitHubActionsECR).
  • Click Trust relationships > Edit trust policy.
  • Replace the existing policy with:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "https://github.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG_OR_USER>/<REPO_NAME>:*"
                }
            }
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

(Replace with your AWS account ID)
(Replace / with your GitHub organization and repository name)

Image description

  • Click Update policy.

Step 5: Configure GitHub Actions Workflow In your GitHub repository:

  • Go to Settings > Secrets and variables > Actions ->Add new repository secret:

  • Name: AWS_DB_URL
    Value: AWS RDS full path for example postgres://db_username:password@rds instance name:5432/DB name

  • Name: AWS_ECR_URI
    Value: ECS repo path for example AWS_ AccountID.dkr.ecr.us-east-2.amazonaws.com/backend-microservices/user-service-stage

  • Name: AWS_REGION
    Value: us-east-2

  • Name: AWS_ROLE_ARN
    Value: The ARN of the IAM role you created (found in AWS IAM).

Image description

Step 6: Update GitHub Actions Workflow (.github/workflows/deploy.yml)

Modify your workflow YAML file to assume the IAM role:

name: Deploy services to Stage AWS ECR and ECS

on:
  push:
    branches:
      - stage
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: 1.23

      - name: Install dependencies
        run: go mod tidy

      - name: Run Integration Tests
        run: go test -v ./integration_test/...

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          role-session-name: GitHubActionsSession
          aws-region: ${{ secrets.AWS_REGION}}
          audience: https://github.com

      - name: Load Environment Variables
        run: |
          cat .env_stage.example >> $GITHUB_ENV

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build Docker Image for user-service
        run: |
          docker build \
            --build-arg logLevelEnvVar=${LOG_LEVEL} \
            --build-arg databaseURLEnvVar=${{secrets.AWS_DB_URL}} \
            --build-arg portEnvVar=${PORT} \
            --build-arg dBEnvVar=${DB} \
            --build-arg dBMaxIdleEnvVar=${DB_MAX_IDLE} \
            --build-arg dBMaxOpenEnvVar=${DB_MAX_OPEN} \
            --build-arg dBMaxLifeTimeEnvVar=${DB_MAX_LIFE_TIME} \
            --build-arg dBMaxIdleTimeEnvVar=${DB_MAX_IDLE_TIME} \
            --build-arg zapConf=${ZAP_CONF} \
            --build-arg gormConf=${GORM_CONF} \
            --build-arg pprofEnable=${PPROF_ENABLE}  \
            -t ${{secrets.AWS_ECR_URI}}user-service-stage:latest \
            -f service/user_service/Dockerfile  \
            .
          docker push ${{secrets.AWS_ECR_URI}}user-service-stage:latest

      - name: Deploy user-service to AWS ECS
        run: |
          aws ecs update-service --cluster cluster-backend-microservice --service service-user --force-new-deployment
Enter fullscreen mode Exit fullscreen mode

Step 7: Test the Workflow

  • Push a commit to the repository.
  • Navigate to Actions in GitHub and verify that the workflow runs successfully.
  • Your Docker image should now be pushed to Amazon ECR and ECS

Conclusion

Now your GitHub Actions workflow can push images to AWS ECR and ECS without requiring long-lived AWS credentials. This setup is more secure and efficient, enabling seamless container deployments from GitHub to AWS. 🎉

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post

Top comments (1)

Collapse
 
shomaail profile image
Shamaail Jafri •

Excellent Post

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post