Containers
Building multi-arch containers with GitHub Actions in AWS
This blog was authored by Zakiya Randall, Technical Account Manager and co-written with Muru Bhaskaran, Sr. Specialist Solutions Architect.
Introduction
As the landscape of computing continues to evolve, there is a growing emphasis on supporting a diverse range of computing architectures. This shift is driven by the need for flexibility, efficiency, and performance optimization across different hardware platforms. Consequently, it has become increasingly important for developers and organizations to build container images that are compatible with multiple architectures (multi-arch).
AWS CodeBuild is a fully managed continuous integration service that now supports managed GitHub Actions runners, which are self-hosted runners that allow users to configure their CodeBuild projects to receive GitHub Actions workflow job events. In this post, we demonstrate a solution that uses GitHub, GitHub Actions workflows, and CodeBuild to build native container images for both x86 and AWS Graviton-based compute on AWS. Upon completion of our GitHub Actions workflow, we will proceed to push our multi-arch images to Amazon Elastic Container Registry (Amazon ECR).
Solution overview
The architecture diagram illustrates the workflow that occurs upon committing a change to the GitHub repository, detailing the subsequent steps involved in pushing the container image to Amazon ECR.

Figure 1: Solution architecture diagram
- Committing a change to the GitHub repository triggers the workflow
- CodeBuild runners for both architectures are started to build the container images
- The code is checked out from the GitHub repository
- Credentials are configured for access to the AWS account
- A role is used to log in to Amazon ECR
- The multi-arch image is built with the list of images for both architectures
Prerequisites
The following prerequisites are necessary to complete this solution:
- AWS account
- Amazon Command Line Interface (AWS CLI)
- A GitHub repository
Walkthrough
The following steps walk you through this solution.
Creating GitHub repository files
To begin creating the solution, you need a GitHub repository to store the Dockerfile, index.html file, and GitHub Actions workflow YAML file. Refer to Creating a new GitHub repository for step by step instructions. For this example, the following files should be committed to the root of the GitHub repository.
index.html
file
Dockerfile
instructions for building the container image image
Create two CodeBuild projects for the x86 and arm64 compute architectures
You must create two CodeBuild projects to run your GitHub Actions jobs. Your CodeBuild projects should follow the following naming structure for <project-name>-x86 and <project-name>-arm64. Refer to the following tutorial to set up two CodeBuild projects for the x86 and arm64 compute environments. You should use the OAuth app authentication method to connect with your GitHub repository. For the x86 and arm64 CodeBuild projects, choose a supported environment image that matches each compute architecture. Your Buildspec build specifications are ignored. Instead, CodeBuild overrides it to use commands that setup the compute runner.

Figure 2: CodeBuild Projects for x86 and arm64
Create an Amazon ECR repository
You also need to create an Amazon ECR repository to store the x86 and arm64 container images. Run the following AWS CLI command to create an Amazon ECR repository.
After creating and defining the Amazon ECR repository, you must define a role so that the CodeBuild runners can have permission to access and push your images to your Amazon ECR repository. The following role that you create allows you to push images to your Amazon ECR repository.
- Go to the IAM console and create a policy with the following permissions. In the Resource section for the AllowPushPull statement in the policy, replace your AWS Region, account number, and repository name with the Amazon Resource Name (ARN) that links to your private repository within Amazon ECR. Specify a name for this policy and choose Create Policy.
After creating the policy, go to the AWS Identity and Access Management (IAM) console to create an Identity Provider and choose OpenID Connect. For the Provider URL, choose https://token.actions.githubusercontent.com. For the Audience, choose sts.amazonaws.com.
2. After you create the provider, create a role and choose Web Identity. In the drop-down box, you should see the Provider URL for https://token.actions.githubusercontent.com. Choose this option and specify sts.amazonaws.com for your Audience. In the GitHub organization, specify your GitHub Organization and add the repository that you created in the initial setup. Choose Next.

Figure 3: Example of creating the role
3. On the Add Permissions page, choose the policy that you created in Step 1 so that you can push images to Amazon ECR. Choose Next. On the next screen, name the role and choose Create role.

Figure 4: Example of adding policy permissions
4. Go to Settings within your GitHub repository, and under Security in the left pane, choose Secrets and Variables. Choose the Actions tab within Secrets and Variables. Choose New repository secret. For the name, enter AWS_ROLE_ARN, enter the AWS Role ARN of the role that you created in Step 3, and choose Add secret.

Figure 5: Example of creating GitHub Actions secret for the AWS Role
5. Create another New repository secret for AWS_REGION. Specify the Region in which you created your resources and choose Add secret.

Figure 6: Example of GitHub Actions secret for the AWS Region
Prepare GitHub Actions workflow
A GitHub Actions workflow is a configurable automated process made up of one or more jobs and you can define these jobs in a YAML file. You are going to create a YAML file in the .github/workflows
directory within your GitHub repository that defines the workflow for the solution. The YAML file for your GitHub Actions workflow contains the build jobs designated for your CodeBuild runners. The runner environment is specified within the runs-on section of the YAML file, which refers to each CodeBuild project that you create for your multi-arch solution.
- container-image.yaml
In the env variables
section within your GitHub Actions workflow configuration file, you must define the Amazon ECR repository that you have created so that your GitHub Actions jobs know where to push your container manifest and images. Your created repository is placed within the env variable
for IMAGE_NAME
.
In your GitHub Actions workflow YAML file, you must define both CodeBuild projects within the runs-on value to define what compute architecture your hosted runners are using to execute your jobs. Here we have defined the arm64 and x86 variables in the matrix
field. A job runs for each combination of the variables that are defined within the arch
field in the matrix. You must specify the CodeBuild project name as a prefix for your job to be picked up by the CodeBuild runner.
In your GitHub Actions workflow configuration file, the GitHub secrets variables are defined for AWS_ROLE_ARN
and AWS_REGION
. GitHub pulls these secret variables when we need to configure your credentials to access AWS.
After all of the files are uploaded to your GitHub repository, your repository should look similar to the following image. The Dockerfile and the index.html file are placed within the root of the repository, and the container-image.yaml file is placed in the .github/workflows directory to define your GitHub Actions workflow.

Figure 7: Example of file structure within the GitHub repository
Inside the .github/workflows folder is where your container-image.yaml file is stored.

Figure 8: Example of GitHub Actions workflow YAML file
Testing the solution
Now that all of your resources are created within GitHub and AWS, it is time to test the solution. Change the message in your index.html file within your GitHub repository and commit your changes to the main branch so that your GitHub Actions workflow can trigger. When your GitHub Actions workflow triggers, your CodeBuild runners should start to execute the jobs that we have specified in your configuration file.
- In your index.html file, change the message in the body of the text. Commit your changes and push to the main branch.
- Go back to the home page of your GitHub repository and choose Actions in the top panel. When you choose Actions, you should see a page that describes the jobs that are running for the build process for both compute architectures as shown in the following figure

Figure 9: Build jobs starting for both compute architectures
3. Within each build job, you should see the steps that the build process is completing for both compute architectures. It states that its waiting for a runner to pick up this job

Figure 10: x86 compute runner

Figure 11: arm64 compute runner
4. Go to CodeBuild in the AWS Console, you should see that both of our build projects for our compute architectures are now In-Progress. It may take a few minutes for the build to complete.

Figure 12: CodeBuild projects for both architectures
5. If you go back to the Actions page within your GitHub repository, then you can see that both build jobs have completed for the x86 and arm64 compute architectures. The manifest job is creating a manifest list that contains your x86 and arm64 container images.

Figure 13: Completed builds in the GitHub Actions page
6. If you go into your Amazon ECR repository, then you should see that the images have been updated for your x86 and arm64 container images for your manifest.

Figure 14: Completed image build in ECR
Cleaning up
To avoid incurring any further costs, make sure you destroy all the infrastructure that you provisioned in relation to the examples detailed in this post. For cleaning up the GitHub resources, you can delete the repository that was used for this solution. To clean up the AWS resources, you can delete the two CodeBuild projects with the following commands.
You can delete your Amazon ECR repository by using the following command.
Conclusion
In this post, we demonstrated how to integrate GitHub Actions with AWS CodeBuild to build multi-arch images. We also walked through the process of how to store these multi-arch images in Amazon ECR so that they can be retrieved by x86 or Amazon Elastic Compute Cloud (Amazon EC2)-AWS Graviton compute. CodeBuild offers a dedicated website that supplies further information, tutorials, and resources designed to assist users in initiating the deployment of runners to enhance their pipelines. If you want to know more about Graviton compute, refer to our website.