Skip to content

Commit

Permalink
feat(build-and-push-ecr): Creates a new action for build/push ECR ima…
Browse files Browse the repository at this point in the history
…ges to central account using oidc login (#24)
  • Loading branch information
OysteinVesth authored Sep 19, 2023
1 parent 9ca8689 commit a999579
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
49 changes: 49 additions & 0 deletions build-and-push-ecr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Build and Push ECR

This action is used to build a docker image and push it to AWS ECR. This image will then be available throughout the 24SO AWS organization.

The image that is built will get the following URI (which is available as an output of the action `image_uri`). `${{ env.CENTRAL_ECR_REPOSITORY_ACCOUNT_ID }}.dkr.ecr.eu-west-1.amazonaws.com/${{ inputs.workload_name }}//${{ inputs.image_name }}:<review | prod>-${{ inputs.tag }}`. Which means that the tag will be end up being `<review | prod>-${{ inputs.tag }}`. Whether it is `prod-` or `review-` is determined by the `review` flag, if set to `false` (default), it will be `prod-`. Ensure that production workload _only_ use `prod-` images, as `review-` images are deleted after a fortnight.

It is important that the `workload_name` matches your actual workload, if it does not, the deployment role will not be allowed to push the image. If you're unsure about the name, just ask someone from Team AWSome.

Example usage for a repository that has a docker file under a folder called **api**.
```yaml
name: ECR Push

on:
push:
branches:
- "**"

jobs:
build_and_push:
runs-on: ubuntu-latest
environment: dev
permissions:
id-token: write
contents: read

steps:
- name: Checkout Code
uses: actions/checkout@v2

- name: Build and Push to ECR
id: ecr
uses: tfso/action-helpers/build-and-push-ecr@v1
with:
ecr_account_id: ${{ env.CENTRAL_ECR_REPOSITORY_ACCOUNT_ID }}
workload_name: apiworker-example
image_name: api-example
tag: v1.0.4
team: awsome
service: example.tfso.io
file: api/Dockerfile
# review: true # This should be true on branches/prerelease

- name: Display Outputs
run: |
echo "Image URI: ${{ steps.ecr.outputs.image_uri }}"
echo "Image tag: ${{ steps.ecr.outputs.image_tag }}"
echo "Repository ARN: ${{ steps.ecr.outputs.repository_arn }}"
```
103 changes: 103 additions & 0 deletions build-and-push-ecr/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: "Build and Push to ECR"
description: "Action to build and push Docker image to ECR using OIDC"
inputs:
ecr_account_id:
description: "AWS ECR Account ID"
required: true
workload_name:
description: "Name of the AWS workload"
required: true
image_name:
description: "Docker Image Name"
required: true
team:
description: "TFSO team name"
required: true
service:
description: "Name of the service the image belongs to"
required: true
context:
description: "Build context"
required: false
default: "."
file:
description: "Which Dockerfile to run"
required: false
default: "Dockerfile"
push:
description: "Should image be pushed to ECR registry"
required: false
default: true
review:
description: "Will prefix image with `review-` if true, prefixed to `-prod` if not."
required: false
default: false
tag:
description: "Tag for the Docker image"
required: true
outputs:
image_uri:
description: 'The full image name that was pushed'
value: "${{ steps.login-ecr.outputs.registry }}/${{ steps.env.outputs.repository_prefix }}${{ inputs.workload_name }}/${{ inputs.image_name }}:${{ inputs.tag }}"
image_tag:
description: 'Image tag'
value: "${{ inputs.tag }}"
repository_arn:
description: 'The unique amazon resource name of the repository'
value: "arn:aws:ecr:eu-west-1:${{ inputs.ecr_account_id }}:${{ steps.env.outputs.repository_prefix }}${{ inputs.workload_name }}/${{ inputs.image_name }}"

runs:
using: "composite"
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Determine env
id: env
shell: bash
run: |
echo "role_postfix=$(if [ "${{ inputs.review }}" == true ]; then echo "-review"; else echo "-prod"; fi)" >> $GITHUB_OUTPUT
echo "repository_prefix=$(if [ "${{ inputs.review }}" == true ]; then echo "review-"; else echo ""; fi)" >> $GITHUB_OUTPUT
- name: Configure AWS credentials for Dev
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: arn:aws:iam::${{ inputs.ecr_account_id }}:role/ecr-${{ inputs.workload_name }}${{ steps.env.outputs.role_postfix }}
aws-region: eu-west-1
role-session-name: GitHubActionsCICD
role-duration-seconds: 3600

# Create ECR repository (or ignore error if already created)
- name: Create or Find ECR Repository
shell: bash
run: |
aws ecr create-repository \
--image-tag-mutability IMMUTABLE \
--repository-name ${{ steps.env.outputs.repository_prefix }}${{ inputs.workload_name }}/${{ inputs.image_name }} \
--tags Key=team,Value=${{ inputs.team }} Key=service,Value=${{ inputs.service }} || true
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1
id: login-ecr
with:
mask-password: "true"
registries: "${{ inputs.ecr_account_id }}"

- name: Build and Push Docker Image
uses: docker/build-push-action@v4
with:
context: ${{ inputs.context }}
file: ${{ inputs.file }}
push: ${{ inputs.push }}
tags: ${{ steps.login-ecr.outputs.registry }}/${{ steps.env.outputs.repository_prefix }}${{ inputs.workload_name }}/${{ inputs.image_name }}:${{ inputs.tag }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
provenance: false

0 comments on commit a999579

Please sign in to comment.