Integrating Your Codeship CI/CD Pipeline with AWS ECR

Written by: Brendan Fosberry
5 min read

Amazon recently announced its hosted EC2 Container Registry. Now that support for Amazon ECR has been released, we’re here to show you how you can integrate ECR into your CI/CD pipeline at Codeship.

ECR behaves similarly to a standard Docker registry where you can push and pull images and reference the registry when building your images. That being said, there are some differences between integrating Docker Hub or Quay and integrating with ECR. Let’s explore integrating with ECR, with a focus on Codeship tooling.

How It Works

Build on the reliable AWS infrastructure, Amazon provides a highly available container registry that integrates directly with the core AWS toolset. This sits behind standard AWS authentication and routing and allows you to easily co-locate your container images with your container cluster.

Quay and Docker Hub, which provide a single endpoint for interaction, use credentials to determine access and visibility. ECR provides a unique URL for each registry, which is tied to a specific user account. This means that different repositories may belong to different registries and have different URLs depending on what user account they were created under. The AWS CLI lets you specify this registry ID when creating repositories.

ECR is compatible with the Docker registry V2 API, which means you can run standard docker pull and docker push commands against your registry. However, this is protected by a layer of security.

In order to do a docker login, you must use the AWS CLI to get a temporary login token, which you can configure to expire up to 36 hours. This means that standard practices of keeping a dockercfg with persistent registry credentials locally, and as part of your encrypted CI databag, will not work with for ECR. We’ll talk in more detail about how we solve this for the Codeship CI/CD pipeline later.

Getting Started

In order to begin using ECR and then integrate it with our CI/CD pipeline, we’ll need to first set up the AWS CLI, create a repository, and determine our registry URL.

To set up the AWS cli, follow the instructions in the AWS CLI docs and then run aws configure to provide the tool with your AWS access credentials.

From here on, all ECR-related commands are available via the aws ecr section and can be listed by running aws ecr help:

$ aws ecr help
NAME
       ecr -
DESCRIPTION
       The  Amazon EC2 Container Registry makes it easier to manage public and
       private Docker images for AWS or on-premises environments. Amazon ECR
       supports resource-level permissions to control who can create, update,
       use or delete images. Users and groups can be created individually in
       AWS Identity and Access Management (IAM) or federated with enterprise
       directories such as Microsoft Active Directory. Images are stored on
       highly durable AWS infrastructure and include built-in caching so that
       starting hundreds of containers is as fast as a single container.
AVAILABLE COMMANDS
       o batch-check-layer-availability
       o batch-delete-image
       o batch-get-image
       o complete-layer-upload
       o create-repository
       o delete-repository
       o delete-repository-policy
       o describe-repositories
       o get-authorization-token
       o get-download-url-for-layer
       o get-login
       o get-repository-policy
       o help
       o initiate-layer-upload
       o list-images
       o put-image
       o set-repository-policy
       o upload-layer-part

Let’s start by creating a repository within our registry for a sample application, myuser/myapp. This will allow us to push and pull images using the Docker cli and API.

$ aws ecr create-repository --repository-name myuser/myapp
{
    "repository": {
        "registryId": "108487657846",
        "repositoryName": "myuser/myapp",
        "repositoryArn": "arn:aws:ecr:us-east-1:108487657846:repository/myuser/myapp"
    }
}

We can now use the registryId field to determine the registry URL via the template https://${REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com. This will be needed later when referencing images. You can also get the registry URL from a generated ECR dockercfg.

Generating Credentials

Since ECR adheres to standard AWS authentication, you must use a secondary, temporary token rather than an AWS keypair in order to push or pull images. This can be accomplished by either generating a Docker login via the AWS cli or simply generating a Docker auth token which can be used to log in.

$ aws ecr get-login
docker login -u AWS -p CiBwm0YaIyYjCVV+BAIBEICCAoo55cBYr9IBaPchhO8Ba0iPy8xRFuvIOSaw2yHVV/lE1/v5e9FZGck03lrA7q/rAFHRjvCrOdSS+/cvV2kpFv1drVEiMR9EEDRKdgLEw4ung3YrKDHqVZjXhxWaRiC2mFIKaDFNjyNYxY6Kmg5JCJTCwHRjOoWADJ0SJRDJdcqN8oKkyUvCEgW8idIWsFw5pjCLtQNtI2VX3XrnE8s5GLddQIsJOG3d1ak3a8LFzXUVb+V3eOysAuLtrCcZlPGyODZHI1nfcgcqjh16zeNitqRI2+H8G+kGAL2Xlbzwp8gVNkH+AX/vkbi0/1QFy/8KgyC7jvnn3+gedXqjNSW4sDS0yjCyp6pL+S4MVTkyq8fkrB/tdgRtJm5n1G6uqeekXuoXXPe5UFce9Rq8/14xKABgEBAgB4cJtGGiEiXkbSZuZ9RurqnnpF7qF1z3uVBXHvUavP9eMAAALXMIIC0wYsXHix4VRzWyzUbB8PANn/Qojf1oMQkQ2u15CZJ8Tol0LHgDi5/qGZ+wHTn+sz/dilpwlmrTuo+6avfZdfQy9r47+EPohNB0OquH03gt3fSjR5efU0ldE62VL/GrgHpgOH9qfSsCDvnKDuwfD5lFEIc3npcLh3djbcchTzCSqHdjAjgQgMQh54JSojL3TydS8WclKg6/W7wQIaozk+zfOoETPq90nO1UtT9QbBxbBBqL1JOs9Wu1owX1Ec9wS5oIuwXYNpHqDTA0EQTV4jZsZ335JMAijcM5GHN7MJ2ukOXOffonmHKoVdNJ7RpLBdz8moVKewhOF4jSh8GMbWu19W3uJsGHyS1oMfZz17whuWdetF77cf5cSUF7HXJEW77zDGRUVo0PWqg2CNEdCaonasScWKLQcT1AjhrQ+ctiXZcjoZGRRxFIZ8qR6t3lwn+sZIGszRkdhEI3lKW7EfZl4PfJVieip8m4sccbcetUzjLeSJeJKoZIhvcNAQcGoIICxDCCAsACAQAwggK5BgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGyzVF8QSt9pZg9PIg== -e none https://108487657846.dkr.ecr.us-east-1.amazonaws.com

The generated command contains the URL for the ECR registry. This command can be directly executed via a subshell:

$ $(aws ecr get-login)
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded

Alternatively, you can manually generate a token using the AWS cli:

$ aws ecr get-authorization-token --query authorizationData[].authorizationToken --output text | base64 -d | cut -d: -f2
CiBwm0YaIyYjCVV+BAIBEICCAoo55cBYr9IBaPchhO8Ba0iPy8xRFuvIOSaw2yHVV/lE1/v5e9FZGck03lrA7q/rAFHRjvCrOdSS+/cvV2kpFv1drVEiMR9EEDRKdgLEw4ung3YrKDHqVZjXhxWaRiC2mFIKaDFNjyNYxY6Kmg5JCJTCwHRjOoWADJ0SJRDJdcqN8oKkyUvCEgW8idIWsFw5pjCLtQNtI2VX3XrnE8s5GLddQIsJOG3d1ak3a8LFzXUVb+V3eOysAuLtrCcZlPGyODZHI1nfcgcqjh16zeNitqRI2+H8G+kGAL2Xlbzwp8gVNkH+AX/vkbi0/1QFy/8KgyC7jvnn3+gedXqjNSW4sDS0yjCyp6pL+S4MVTkyq8fkrB/tdgRtJm5n1G6uqeekXuoXXPe5UFce9Rq8/14xKABgEBAgB4cJtGGiEiXkbSZuZ9RurqnnpF7qF1z3uVBXHvUavP9eMAAALXMIIC0wYsXHix4VRzWyzUbB8PANn/Qojf1oMQkQ2u15CZJ8Tol0LHgDi5/qGZ+wHTn+sz/dilpwlmrTuo+6avfZdfQy9r47+EPohNB0OquH03gt3fSjR5efU0ldE62VL/GrgHpgOH9qfSsCDvnKDuwfD5lFEIc3npcLh3djbcchTzCSqHdjAjgQgMQh54JSojL3TydS8WclKg6/W7wQIaozk+zfOoETPq90nO1UtT9QbBxbBBqL1JOs9Wu1owX1Ec9wS5oIuwXYNpHqDTA0EQTV4jZsZ335JMAijcM5GHN7MJ2ukOXOffonmHKoVdNJ7RpLBdz8moVKewhOF4jSh8GMbWu19W3uJsGHyS1oMfZz17whuWdetF77cf5cSUF7HXJEW77zDGRUVo0PWqg2CNEdCaonasScWKLQcT1AjhrQ+ctiXZcjoZGRRxFIZ8qR6t3lwn+sZIGszRkdhEI3lKW7EfZl4PfJVieip8m4sccbcetUzjLeSJeJKoZIhvcNAQcGoIICxDCCAsACAQAwggK5BgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGyzVF8QSt9pZg9PIg==

You can then use the returned authorization token in the same docker login command aws ecr get-login generates.

Authentication with ECR in Codeship

Traditionally, static Docker credentials are encoded in the project databag and decrypted in order to push or pull images from a registry.

Due to the short-lived nature of ECR credentials, Codeship has added support for dockercfg generation services. You can now specify a service with which to generate a dockercfg for authenticating a specific service or step. You can find out more about this in the Codeship documentation. For the purposes of ECR support, we maintain a Docker image that you can extend or use directly.

A typical integration involves defining a service to generate a dockercfg for your registry in your services file and listing that as the authentication source for specific services and/or steps.

# codeship-services.yml
app:
  build:
    image: 108487657846.dkr.ecr.us-east-1.amazonaws.com/myuser/myapp
    dockerfile_path: ./Dockerfile
aws_generator:
  image: codeship/aws-ecr-dockercfg-generator
  encrypted_env_file: aws_creds.encrypted # contains Secret, AccessKey and Region
  add_docker: true
# codeship-steps.yml
- type: push
  service: app
  registry: https://108487657846.dkr.ecr.us-east-1.amazonaws.com
  image_name:  108487657846.dkr.ecr.us-east-1.amazonaws.com/myuser/myapp
  dockercfg_service: aws_generator

The aws_generator service will be run as needed and provides credentials to allow Codeship to interact with your ECR registry. In this example, we’re simply building an image and having our CD pipeline push it to ECR.

Using ECR Base Images and Caching

Along with explicitly pushing images to ECR as part of your pipeline, you can leverage your registry to host private base images used during a Codeship build.

In this case, as long as the step or service referencing the image being built references the dockercfg_service, and the FROM declaration in your Dockerfile references the full ECR image name, the build will work. Similarly, this will allow you to use ECR to populate your local Docker image cache during builds by specifying cached: true on relevant services.

# Dockerfile
FROM 108487657846.dkr.ecr.us-east-1.amazonaws.com/myuser/myapp
ADD ./ /opt/app
# codeship-services.yml
app:
  build:
    image: myuser/myapp
    dockerfile_path: ./Dockerfile
  dockercfg_service: aws_generator
  cached: true
aws_generator:
  image: codeship/aws-ecr-dockercfg-generator
  encrypted_env_file: aws_creds.encrypted # contains Secret, AccessKey and Region

Conclusion

Using dockercfg generator services from Codeship and integrating your existing CI/CD pipeline with ECR is a simple task. By adding a generator service, updating your image names, and replacing any existing dockercfg references with references to the new dockercfg generator service, you can push your images to ECR without making complex changes to your pipeline.

With the ability to co-locate your image registry with your containers, ECR is a powerful tool to help speed up the deployment and scaling of your AWS infrastructure.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.