DEV Community

Cover image for Github Actions - Using a AWS ECR image as a container
Perry H
Perry H

Posted on

Github Actions - Using a AWS ECR image as a container

Recently, I've been migrating pipelines from Bitbucket to Github Actions, and I've encountered some issues due to the differences between Bitbucket pipelines and Github Actions. One of the things that slowed me down was using private images as pipeline containers. We use images from our AWS ECR private registry in some of our Bitbucket pipelines. As I couldn't find much documentation on how to use ECR and Github Actions and even found the official documentation lacking, I wanted to write down the steps I took so others could set them up easier.

Configuration

The first step is to configure your workflow to use a container with an ECR image.

build:
    runs-on: ubuntu-latest
    container:
      # your image from ecr goes here
      image: <aws-acount>.dkr.ecr.<region>.amazonaws.com/<my_image>:<version>
      # the credentials are specified below in a secret
      credentials:
        username: AWS
        # you can call the secret whatever you like
        password: ${{ secrets.AWS_ECR_PW }}
Enter fullscreen mode Exit fullscreen mode

Automation

One thing to note, the ECR password is only valid for 12 hours. If you want to avoid manually updating the secret, you can set up automation using Github Actions similar to this post.

Here is a workflow that automatically updates the password every 11 hours.

name: Update ECR PW

on:
  schedule:
    # CodeArtifact token expires in 12 hours, update token every 11 hours
    - cron: 02 */11 * * *
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  update-ecr-pw:
    runs-on: ubuntu-latest
    # These permissions are needed to interact with GitHub's OIDC Token endpoint.
    permissions:
      id-token: write
      contents: read
    env:
      # need an Github Access token with Admin access to update secret
      GH_TOKEN: ${{ secrets.GH_CLI }}
    steps:
      - uses: actions/checkout@v3
      - uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-region: <your_region>
          # should be the arn to your role created for oidc
          role-to-assume: arn:aws:iam::<your_aws-account>:role/<your-role-name>
      - name: Get pw and update secret
        run: |
          export ECR_PW=`aws ecr get-login-password --region <your_region> --output text`
          gh secret set <YOUR_SECRET> --org <your-org> --visibility all --body "$ECR_PW"
Enter fullscreen mode Exit fullscreen mode

If you don't understand the code above or don't have OIDC setup for your Github Actions, the post mentioned above dives into more details and it provides documentation on how to set that up. It only takes a couple of minutes to get set up.

This is the way I set up a Github Action to use an image from a private ECR account. This is done by specifying the image, username, and password under the container key in the workflow file. I also showed how to add automation to update the password to reduce manual input. If you have other ways to automate these steps, let me know in the comments.

Photo by Digital Buggu: https://www.pexels.com/photo/colorful-toothed-wheels-171198/

Top comments (1)

Collapse
 
jurriaanpro profile image
Jurriaan Proos

Good stuff! Would it be acceptable to have a job that fetches the ECR password and passes it on to the next job that requires it using job outputs or am I breaking some security rules there?

So you get something like

jobs:
  fetch-ecr-password:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    outputs:
      ecr_pw: ${{ steps.get-ecr-pw.outputs.ecr_pw }}
    steps:
      # Checkout repository
      - uses: actions/checkout@v4
      # Configure AWS credentials
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: <region>
          role-to-assume: <role>
      - id: get-ecr-pw
        run: |
          echo "ecr_pw=$(aws ecr get-login-password --region <region> --output text)" >> "$GITHUB_OUTPUT"
  run:
    runs-on: ubuntu-latest    
    needs: fetch-ecr-password
    container:
      image: <aws-acount>.dkr.ecr.<region>.amazonaws.com/<my_image>:<version>
      credentials:
        username: AWS
        password: ${{ needs.fetch-ecr-password.outputs.ecr_pw }}   
    steps:
      - run: echo "Hello from container from private ECR"
Enter fullscreen mode Exit fullscreen mode