Build and Release Container Image to Amazon Elastic Container Registry (ECR) via Amazon CodeCatalyst
Tags: aws, codecatalyst, ecr, cicd
Published: 2023-09-16 05:20:25

In this blog, I will discuss how to build and release container image to Amazon Elastic Container Registry (ECR) using service that by the time this blog is released, the service is quite new which is Amazon CodeCatalyst.

Before continue further, I would like to explain briefly about Amazon CodeCatalyst. As referred from Amazon CodeCatalyst [documentation](https://docs.aws.amazon.com/codecatalyst/latest/userguide/welcome.html):

> Amazon CodeCatalyst is an integrated service for software development teams adopting continuous integration and deployment practices into their software development process. CodeCatalyst puts the tools you need all in one place. You can plan work, collaborate on code, and build, test, and deploy applications with continuous integration/continuous delivery (CI/CD) tools.

## Scenario

In this blog, I will discuss how to build and release container image with GitHub as source code repository. Then Amazon CodeCatalyst will run pipeline/workflow used for build and release container image, then later container image will be sent to ECR. The topology would be like this:

![codecatalyst push to ecr workflow](https://ludesdeveloper.files.wordpress.com/2023/08/codecatalyst-push-to-ecr-workflow.png)

## Prerequisites

- Before starting configuration, if you have not got AWS Builder ID account, please sign up first
- After sign up, go to Amazon CodeCatalyst web console to start project and configuration
- Create repository for container image in Amazon ECR

## Configuration Steps

### Amazon ECR Repository Configuration

In this blog, I created ECR repository using Terraform with remote backend (Terraform Cloud). ECR repository created with reference from terraform public module [terraform-aws-modules/terraform-aws-ecr](https://registry.terraform.io/modules/terraform-aws-modules/ecr/aws/latest).

Below is file or directory structure used by Terraform codes:

```
└── ecr/
    └── region-name/
        ├── files/
        │   └── policies/
        │       └── expire-untagged-images.json
        ├── main.tf
        ├── resources.tf
        └── variables.tf
```

Here are the configuration steps:

1. Define Terraform configuration inside file **main.tf**. In this configuration, I declared remote backend (Terraform Cloud), workspace used by Terraform, provider and its version and also AWS region that declared from variable

    ```
    ###########################
    # Terraform Configuration #
    ###########################

    terraform {
      backend "remote" {
        hostname     = "app.terraform.io"
        organization = "my-organization"
    
        workspaces {
          name = "my-ecr-workspace"
        }
      }
    }
    
    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 5.11.0"
        }
      }
    
      required_version = ">= 1.3.0"
    }

    provider "aws" {
      region = var.aws_region
    }
    ```

2. Define variable inside file **variables.tf**

    ```
    variable "aws_region" {
      type        = string
      description = "AWS Region"
      default     = "ap-southeast-1"
    }
    ```

3. Define ECR repository creation using public module reference as mentioned above. I also defined repository lifecycle policy so that untagged image will be expired after period amount of time. This configuration is defined in file **resources.tf**

    ```
    ####################
    # ECR Repositories #
    ####################
    
    module "my_repository" {
      source  = "terraform-aws-modules/ecr/aws"
      version = "1.6.0"
    
      repository_name             = "my-repository"
      repository_lifecycle_policy = file("${path.module}/files/policies/expire-untagged-images.json")
    
      tags = {
        Name             = "my-repository"
        "my:environment" = "my-environment"
      }
    }
    ```

4. Policy file reference expire-untagged-images.json is contain this instruction

    ```
    {
        "rules": [
            {
                "rulePriority": 1,
                "description": "Expire images older than 14 days",
                "selection": {
                    "tagStatus": "untagged",
                    "countType": "sinceImagePushed",
                    "countUnit": "days",
                    "countNumber": 14
                },
                "action": {
                    "type": "expire"
                }
            }
        ]
    }
    ```

5. Next commit and push terraform codes to the repository. After that run Terraform plan and Terraform apply from Terraform Cloud workspace so that infrastructures or resources can be provisioned. This activity will not be explained in detail and I will only show the simulation. If you are interested in how to configure Terraform Cloud workspace and how to run Terraform plans and apply for the provision of AWS resources, please check out my other blog post [here](https://aws.plainenglish.io/basic-configuration-how-to-provision-amazon-web-services-aws-resources-via-terraform-cl-5e1d6db8b22f).

    ![tfc plan and apply](https://ludesdeveloper.files.wordpress.com/2023/08/tfc-plan-and-apply.png)

###Amazon CodeCatalyst Pipeline/Workflow Configuration

1. Before starting configuration, please make sure space on Amazon CodeCatalyst has been created. More details on space, please check [Spaces in CodeCatalyst](https://docs.aws.amazon.com/codecatalyst/latest/userguide/spaces.html)

2. Connect Amazon CodeCatalyst space with AWS account. In space page, go to menu Settings > AWS accounts. Click Add an AWS account button

    ![add aws account](https://ludesdeveloper.files.wordpress.com/2023/08/1.-add-aws-account.png)

3. Input required values such as AWS account ID, then display name. Next click Associate AWS account button

    ![associate aws account](https://ludesdeveloper.files.wordpress.com/2023/08/2.-associate-aws-account.png)

4. Next We will be redirected to Amazon CodeCatalyst page in AWS web console. Insert token that has been generated by CodeCatalyst (image for this is not displayed in this blog). Verify space has been connected

5.  Back to AWS account page in CodeCatalyst web console, verify account has been connected as well

    ![verify aws account](https://ludesdeveloper.files.wordpress.com/2023/08/4.-verify-aws-account.png)

6. Add IAM role that will be used to run workflow. Go to account details page by clicking account name in previous point. Then click Manage roles from AWS Management Console button

    ![add iam role](https://ludesdeveloper.files.wordpress.com/2023/08/5.-add-iam-role.png)

7. In this blog, I created administrator IAM role because I just need for development only. On production environment, please bear in mind to always use least privileged method for security concern. Next, set role name and click Create development role button

    ![create iam role for codecatalyst](https://ludesdeveloper.files.wordpress.com/2023/08/6.-create-iam-role-for-codecatalyst.png)

8. Verify IAM role has been created

    ![verify iam role](https://ludesdeveloper.files.wordpress.com/2023/08/7.-verify-iam-role.png)

9. Go back to CodeCatalyst space page and create project by clicking Create project button

    ![create project](https://ludesdeveloper.files.wordpress.com/2023/08/8.-create-project.png)

10. In this blog, I created project with bring your own code method. The codes has been stored in GitHub. Choose GitHub account that will be connected, then choose GitHub repository name. After that, set project name used by CodeCatalyst. If all set, click Create project button

    ![create project bring your own code](https://ludesdeveloper.files.wordpress.com/2023/08/9.-create-project-bring-your-own-code.png)

11. Verify GitHub repository has been connected. In project page, go to menu Code > Source repositories.

    ![verify source repositories](https://ludesdeveloper.files.wordpress.com/2023/08/10.-verify-source-repositories.png)

12. Create environment that will be used by CI/CD workflow/pipeline. Go to menu CI/CD > Environment. Then click Create environment button

    ![create environment](https://ludesdeveloper.files.wordpress.com/2023/08/11.-create-environment.png)

13. In Create environment page, input environment name, environment type and AWS account connection (optional). If all set, click Create environment button

    ![create environment details](https://ludesdeveloper.files.wordpress.com/2023/08/12.-create-environment-details.png)

14. Define CI/CD workflow/pipeline. CodeCatalyst need workflow definition file for pipeline creation. This file can be created by several methods, for example create via CodeCatalyst web console or using code/text editor. Further details about workflow in CodeCatalyst, please check CodeCatalyst documentation [Workflows concepts](https://docs.aws.amazon.com/codecatalyst/latest/userguide/workflows-concepts.html)

    ![create workflow menu](https://ludesdeveloper.files.wordpress.com/2023/08/13.-create-workflow-menu.png)

15. Before creating workflow file, I would like to inform that there are several pre-defined workflow definition files that has been provided. To check those files, go to menu Create workflow > in Actions section, find template file that suitable with your needs. In this blog, for example I will use pre-defined template for workflow push to Amazon ECR. This pre-defined template will help me to simplify build and push container image to Amazon ECR

    ![find workflow push to amazon ecr](https://ludesdeveloper.files.wordpress.com/2023/08/14.-find-workflow-push-to-amazon-ecr.png)

16. We can see the details of each pre-defined template file. For example documentation about how to use, YAML preview etc. To see the details, click pre-defined template name and next will be redirected to detail page

    ![action push to amazon ecr documentation](https://ludesdeveloper.files.wordpress.com/2023/08/15.-action-push-to-amazon-ecr-documentation.png)

17. We also can see the preview of YAML and also the details for example variables used by the template

    ![action push to amazon ecr yaml preview](https://ludesdeveloper.files.wordpress.com/2023/08/16.-action-push-to-amazon-ecr-yaml-preview.png)

18. Next You can adjust with your preference, whether you want to create configuration using visual editor on web console or using code/text editor

19. In this blog, I created configuration using code/text editor and I will explain the details of workflow file

    ```
    # - I created workflow name build-container
    # - Workflow created using reference from pre-defined template `codecatalyst-labs/push-to-ecr@v1.0.1` with source from WorkflowSource which in this blog is GitHub repository
    # - Workflow will run in sandbox environment with AWS account reference as explained above and IAM role that associated within that account
    # - Define ECR repository name, image tag and AWS region

    Name: build-container
    SchemaVersion: "1.0"
    
    Actions:
      build-and-push-to-ecr:
        # Identifies the action. Do not modify this value.
        Identifier: codecatalyst-labs/push-to-ecr@v1.0.1
    
        # Specifies the source and/or artifacts to pass to the action as input.
        Inputs:
          # Required
          Sources:
            - WorkflowSource # This specifies that the action requires this Workflow as a source
    
        # Required; You can use an environment, AWS account connection, and role to access AWS resources.
        Environment:
          Name: sandbox
          Connections:
            - Name: lanandra-sandbox
              Role: CodeCatalystWorkflowDevelopmentRole-lanandra-sandbox
    
    
        # Defines the action's properties.
        Configuration:
          # Required; type: string; description: The name to use for the repository. 
          # The repository name may be specified on its own (such as nginx-web-app) 
          # or it can be prepended with a namespace to group the repository into a category (such as project-a/nginx-web-app)
          RepositoryName: steampipe-container-agent
          ImageTag: v0.1.0
          AWSRegion: ap-southeast-1
    ```

20. Run workflow. In this blog, I did not configured trigger event for workflow that can make workflow run automatically. Thus, I need to run the workflow manually. Go to menu CI/CD > Workflows. In tab Workflows, choose GitHub repository name, branch name and workflow name. Then in Action drop down list, choose Run

    ![run workflow](https://ludesdeveloper.files.wordpress.com/2023/08/17.-run-workflow.png)

21. Next workflow will be running. Verify it by choosing workflow name as mentioned in previous point, then choose tab Runs

    ![workflow run menu](https://ludesdeveloper.files.wordpress.com/2023/08/18.-workflow-run-menu.png)

22. Go to workflow run. Verify run has been running and succeeded. Details of run can be seen inside tab Logs

    ![verify run](https://ludesdeveloper.files.wordpress.com/2023/08/19.-verify-run.png)

23. Verify container image has been created and uploaded to Amazon ECR. Go to ECR service page, then go to repository used or defined in workflow

    ![verify container image](https://ludesdeveloper.files.wordpress.com/2023/08/20.-verify-container-image.png)

## Summary

We have reached the last section of this blog. Here are some key takeaways that can be summarized:

- Amazon CodeCatalyst is service by AWS that provide Continues Integration/Continues Delivery or Deployment (CI/CD) in one place
- CodeCatalyst can be used as alternative for CI/CD engine/tools that have seamless experience if we want to deploy our application to AWS environment
- Currently there are some integration or template that can simplify user for creating CI/CD pipeline

Please check out my GitHub repository to see source code example that used in this blog:

- Terraform code for ECR creation: [ecr](https://github.com/lanandra/mock-aws-infrastructure/tree/master/environment-name/ecr/region-name)
- Amazon CodeCatalyst workflow: [codecatalyst](https://github.com/lanandra/steampipe-container-agent/blob/main/.codecatalyst/workflows/build-container.yaml)

Please comment if you have any suggestions, critiques, or thoughts.

Hope this article will benefit you. Thank you!