Build, Scan, and Push Docker image to Amazon ECR using GitHub Actions

This blog post is the second part of an umbrella series in which I demonstrate how to create and deploy an Amazon Elastic Container Service (ECS) service using Terraform and GitHub Actions. In the first part, I covered creating all the required AWS cloud services to host the ECS service. In this second part, I’ll focus on creating a Docker image from a Dockerfile in GitHub Actions and pushing that image into an Amazon Elastic Container Registry (ECR) repository.

By combining the power of Amazon ECR and GitHub Actions, we can streamline the process of building and deploying your containerized applications, ensuring consistent and reliable deployment across different environments.

Prerequisites
Before we dive into the details, ensure that you have the following prerequisites in place:
– An AWS account and the necessary permissions to create and access Amazon ECR repositories.
– A GitHub code repository containing your application and a Dockerfile.
– Basic understanding of Docker, AWS services, and GitHub Actions workflows.

At a high level, there are three steps to pushing a Docker image to an Amazon ECR repository using GitHub Actions. These are:
1. Create an Amazon ECR Repository
2. Configure AWS Credentials for GitHub Actions and
3. Create a GitHub Actions Workflow

I will now explain these steps in detail.

1. Create an Amazon ECR Repository
91-image-9
Other AWS services, along with the Amazon ECR repository, would be required. I covered how to provision these resources in detail in my article on creating AWS infrastructure to host an Amazon ECS service.

2 . Configure AWS Credentials for GitHub Actions
To authenticate with AWS from your GitHub Actions workflow, you’ll need to configure AWS credentials. Follow the steps outlined in [this detailed guide] to set up the required AWS credentials and store them as a GitHub repository secret.

3. Create a GitHub Actions Workflow
The entire logic of creating and pushing a Docker image is managed in the GitHub Actions YML file.
91-image-8
This workflow file (app-ci-cd.yml) is under the .github/workflows/ directory and contains the steps to build and push the Docker image to Amazon ECR. You can access this from my GitHub repository: add-aws-ecr-ecs-fargate.

I also set a couple of environment variables in the YML file. These are the AWS Region where the Amazon ECR is located and the name of the private repository. I then used several actions from the marketplace to complete the tasks. Let me walk through the YML file and explain it step by step.

(a) Create a unique image tag for the Docker Image:
91-image-2
I set tag_immutability to enabled in the Amazon ECR repository and hence had to ensure that the Docker image tags were unique for each push. I could have used the Git Commit SHA, but I preferred one that gave me better context, like the one I used. This tag contains the pipeline trigger date, the GitHub run number, and the run attempt, ensuring that even if the same pipeline run is re-triggered, it will create a new image tag.

(b) Authenticate to AWS Cloud:
91-image-3
This step uses the aws-actions/configure-aws-credentials action to configure the AWS credentials required for authenticating with AWS services. The action retrieves the IAM_ROLE from the GitHub secrets I set up earlier.

(c) Authenticate to Amazon ECR:
91-image-4
This step uses the aws-actions/amazon-ecr-login action to authenticate with Amazon ECR. This action retrieves an authentication token and configures Docker to use it to push and pull images from Amazon ECR.

The action is from the [AWS Action for Amazon ECR] repository on GitHub. It provides a convenient way to log in to Amazon ECR without manually retrieving and storing the authentication token. The action supports multiple use cases, such as cross-account authentication and integration with AWS CodeBuild.

(d) Build and tag Docker image to Amazon ECR:
91-image-5
In this step, we build the Docker image using the docker build command, tag it with the TAG_NAME environment variable created earlier. Since I had set the working-directory: ./app earlier in the YML file, the build step found the Dockerfile in that location.

(e) Scan Docker image for vulnerabilities:
91-image-6
I used Aqua Security’s Trivy vulnerability scanner to scan the Docker image. This step identifies and addresses potential vulnerabilities in your Docker images before pushing them to Amazon ECR. The next step is to upload the report to the repository’s security findings, which are stored under the Security tab.

(f) Push the Docker image to the Amazon ECR repository:
91-image-7
The last step in the workflow is to push the Docker image to the Amazon ECR repository using the docker push command. The REGISTRY, REPOSITORY and IMAGE_TAG environment variables are used to construct the full image URL. I also set a condition to the step since I did not want it to run in case it is triggered due to a pull request.

Best Practices
I implemented a few best practices, such as (1) separate build and push steps for better control and flexibility, (2) scanning the Docker image for vulnerabilities, and (3) storing the secrets securely using GitHub Secrets. However, there are some more best practices to consider when pushing Docker images to Amazon ECR using GitHub Actions:

  • Use Caching for Faster Builds: GitHub Actions provides caching mechanisms that can significantly speed up your Docker build process by caching layers between builds.
  • Use Semantic Versioning: Implement a versioning strategy for your Docker images using semantic versioning principles. This will make managing and tracking changes over time more convenient.

And that brings us to the end of this note. I hope you enjoyed learning how to automate the process of building and pushing Docker images to Amazon ECR using GitHub Actions. By leveraging the power of these two services, you can streamline your application deployment process, ensuring consistent and reliable deployments across different environments.

If you want, fork out this repository and give it a try. Commit and push your changes to the GitHub repository. That should trigger the GitHub Actions workflow you created, which will build your Docker image and push it to the specified Amazon ECR repository. You can monitor the progress of the workflow under the “Actions” tab of your GitHub repository. If the workflow completes successfully, your Docker image will be available in the Amazon ECR repository. Ensure that you complete the prerequisites before you trigger the workflow. Let me know if you have any questions.
As a next step, I will demonstrate how we can explore integrating this workflow with other AWS services, such as Amazon Elastic Container Service (ECS), to deploy the containerized applications seamlessly.

One thought on “Build, Scan, and Push Docker image to Amazon ECR using GitHub Actions

Leave a comment