Docker image build and publish for ADMIN #7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Docker image build and publish for ADMIN | |
on: | |
workflow_dispatch: | |
inputs: | |
path_to_dockerfile: | |
description: Path to the dockerfile (default = 'Dockerfile') | |
default: "infra/docker/Dockerfile.admin" | |
type: string | |
docker_build_dir: | |
description: Docker build directory (default = '.') | |
default: "." | |
type: string | |
image_tag: | |
description: Tag to apply to images. | |
type: string | |
default: sahil-admin | |
lifecycle_policy_file: | |
description: Path to the lifecycle policy JSON file (default = 'policy.json') | |
default: "policy.json" | |
type: string | |
backend_s3_bucket: | |
description: Name of the S3bucket for Terraform backend | |
default: "sahil-terraform-state-bucket" | |
type: string | |
backend_iam_role: | |
description: Name of the Terraform backend assumable IAM Role | |
default: "workload-assumable-role" | |
type: string | |
github_iam_role: | |
description: Name of the IAM Role for adding access to ECR repo | |
default: "github-actions-role" | |
type: string | |
aws_account_id: | |
description: AWS Account ID | |
default: "060795911441" | |
type: string | |
aws_region: | |
description: Target AWS Region | |
default: "eu-west-1" | |
type: string | |
backend_dynamodb_table: | |
description: DynamoDB table for State lock | |
default: "sahil-terraform-table-locks" | |
type: string | |
# concurrency required to avoid terraform lock contention during ECR provisioning | |
concurrency: ci-${{ github.repository }}-admin-docker-pipeline | |
jobs: | |
docker: | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write | |
contents: read | |
outputs: | |
image_tag: ${{ steps.build-publish.outputs.image_tag }} | |
version_tag: ${{ steps.build-publish.outputs.version_tag }} | |
full_image: ${{ steps.build-publish.outputs.full_image }} | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v2 | |
with: | |
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/sahil-deployment-role | |
aws-region: ${{ inputs.aws_region }} | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v2 | |
with: | |
terraform_wrapper: false | |
- name: prepare ECR repo name based on the Github repository | |
shell: bash | |
run: | | |
set -eux | |
# lowercase the name | |
repo="${GITHUB_REPOSITORY,,}" | |
# replace / with _ | |
echo "ECR_REPO_NAME=${repo//\//_}" >> $GITHUB_ENV | |
- name: TF init | |
shell: bash | |
run: | | |
set -eux | |
terraform init -upgrade -reconfigure \ | |
-backend-config='skip_metadata_api_check=true' \ | |
-backend-config='skip_region_validation=true' \ | |
-backend-config='skip_credentials_validation=true' \ | |
-backend-config='region=${{ inputs.aws_region }}' \ | |
-backend-config='bucket=${{ inputs.backend_s3_bucket }}' \ | |
-backend-config='key=docker-ecr/terraform-${{ env.ECR_REPO_NAME }}.tfstate' \ | |
-backend-config='dynamodb_table=${{ inputs.backend_dynamodb_table }}' \ | |
-backend-config='assume_role={ role_arn = "arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.backend_iam_role }}" }' | |
working-directory: infra/terraform | |
- name: Create ECR repo [TF apply] | |
shell: bash | |
run: | | |
set -eux | |
terraform apply \ | |
-var 'repository_name=${{ env.ECR_REPO_NAME }}' \ | |
-var 'lifecycle_policy=${{ inputs.lifecycle_policy_file }}' \ | |
-var 'iam_role=arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.github_iam_role }}' \ | |
-var 'aws_account_id=${{ inputs.aws_account_id }}' \ | |
-auto-approve | |
working-directory: infra/terraform | |
- name: Login to Amazon ECR | |
id: login-ecr | |
uses: aws-actions/amazon-ecr-login@v2 | |
with: | |
registries: ${{ inputs.aws_account_id }} | |
- name: Build, tag, and push image to Amazon ECR | |
id: build-publish | |
shell: bash | |
env: | |
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
ECR_REPOSITORY: ${{ env.ECR_REPO_NAME }} | |
IMAGE_TAG: ${{ inputs.image_tag }} | |
run: | | |
# Get the current latest image digest (if it exists) | |
PREVIOUS_IMAGE_MANIFEST=$(aws ecr batch-get-image \ | |
--repository-name $ECR_REPOSITORY \ | |
--image-ids imageTag=$IMAGE_TAG \ | |
--output text \ | |
--query 'images[].imageManifest' || echo "") | |
# Build the new image | |
docker build "${{ inputs.docker_build_dir }}" -f "${{ inputs.path_to_dockerfile }}" -t "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" | |
# Push the new image as latest | |
docker push "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" | |
# If there was a previous image, tag it as v1, v2, etc. | |
if [ ! -z "$PREVIOUS_IMAGE_MANIFEST" ]; then | |
# Get the current highest version number | |
CURRENT_VERSION=$(aws ecr describe-images \ | |
--repository-name $ECR_REPOSITORY \ | |
--query 'imageDetails[].imageTags[?starts_with(@, `v`)]' \ | |
--output text | grep -o 'v[0-9]*' | sed 's/v//' | sort -n | tail -1) | |
# Calculate next version number | |
if [ -z "$CURRENT_VERSION" ]; then | |
NEW_VERSION="v1" | |
else | |
NEW_VERSION="v$((CURRENT_VERSION + 1))" | |
fi | |
# Tag the previous image with the new version | |
aws ecr put-image \ | |
--repository-name $ECR_REPOSITORY \ | |
--image-tag $NEW_VERSION \ | |
--image-manifest "$PREVIOUS_IMAGE_MANIFEST" | |
echo "Previous image tagged as $NEW_VERSION" | |
echo "version_tag=$NEW_VERSION" >> $GITHUB_OUTPUT | |
fi | |
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT | |
echo "full_image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT |