Skip to content

Using AWS ECR for Docker

Introduction

Amazon Elastic Container Registry (ECR) is a fully-managed container registry service provided by AWS, designed to store, share, and deploy container images. To use Docker with ECR, you need to authenticate Docker to pull and push images. The qbee-agent does not support ECR authentication out of the box as ECR authentication requires the use of helpers. But it can be easily set up.

Setting up ECR authentication

Enabling your device for ECR authentication is just a matter of deploying the right utilities and configuration files.

/root/.docker/config.json
{
    "credsStore": "ecr-login"
}
/root/.aws/credentials
[default]
region = <AWS_REGION>
aws_access_key_id = <AWS_ACCESS_KEY_ID>
aws_secret_access_key = <AWS_SECRET_ACCESS_KEY>

We would also need the docker-credential-ecr-login utility in on the target device. This is downloadable from here.

Setting up acces in AWS

It is good practice to limit access to bare minimum for any API user. With AWS IAM this can be done on a very granular level. For this example we limit the access for the user account associated with the aws_access_key_id to only access a repository demo with read permissions.

AWS user policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:Get*",
                "ecr:List*",
                "ecr:Describe*",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability"
            ],
            "Resource": "arn:aws:ecr:*:*:repository/demo"
        },
        {
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}

Preparing files for device

Once everything is in place the necessary utitilities and credentials need to be distributed to the target devices. This can be easily done with File Distribution. It is also best practice to store the security credentials as secrets and use those as input parameters to the file distribution. We would therefore need to change the /root/.aws/credentials to template format. Remember to change to AWS_REGION to the region relevant to your deployment.

credentials.template
[default]
region = <AWS_REGION>
aws_access_key_id = {{ecr_aws_access_key_id}}
aws_secret_access_key = {{ecr_aws_secret_access_key}}

Once the template file has been created, the following file structure can be created in the Qbee File Manager:

* /ecr-login/docker/config.json
* /ecr-login/aws/credentials.template
* /ecr-login/aws/docker-credential-ecr-login-x86_64

Setting up secrets

The aws_access_key_id and aws_secret_access_key are secrets and should be treated as such. In Qbee that is done under the secrets section in Parameters.

parameters.json
{
    "enabled": true,
    "extend": true,
    "version": "v1",
    "secrets": [
        {
            "key": "ecr_aws_access_key_id",
            "value": "<AWS_ACCESS_KEY_ID>"
        },
        {
            "key": "ecr_aws_secret_access_key",
            "value": "<AWS_SECRET_ACCESS_KEY>"
        }
    ]
}

NB! Please remember to replace the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with values relevant to the restricted AWS user account set up earlier.

Setting up file distribution

The next thing that needs to be done is to distribute all the necessary files so that docker will be enabled to login into the AWS ECR registry.

file_distribution.json
{
    "enabled": true,
    "extend": true,
    "version": "v1",
    "files": [
        {
            "label": "ECR login",
            "templates": [
                {
                    "source": "/ecr-login/bin/docker-credential-ecr-login-$(sys.arch)",
                    "destination": "/usr/local/bin/docker-credential-ecr-login",
                    "is_template": false
                },
                {
                    "source": "/ecr-login/docker/config.json",
                    "destination": "/root/.docker/config.json",
                    "is_template": false
                },
                {
                    "source": "/ecr-login/aws/credentials.template",
                    "destination": "/root/.aws/credentials",
                    "is_template": true
                }
            ],
            "parameters": [
                {
                    "key": "ecr_aws_access_key_id",
                    "value": "$(ecr_aws_access_key_id)"
                },
                {
                    "key": "ecr_aws_secret_access_key",
                    "value": "$(ecr_aws_secret_access_key)"
                }
            ],
            "command": "chmod +x /usr/local/bin/docker-credential-ecr-login"
        }
    ]
}

Noticed that the docker-credential-ecr-login is post-fixed with $(sys.arch) which is an internal parameter that resolves to the kernel reported archicture for the device. This allows usage of the same configuration across several architectures. Also note that we reference the previously configured secrets as input to the template parameters.

Setting up the docker configuration

Once the file distribution is saved, you can configure Docker Containers to deploy your container.

docker_containers.json
{
    "enabled": true,
    "extend": true,
    "version": "v1",
    "items": [
        {
            "name": "my-ecr-container",
            "image": "<AWS_ACCOUNT>.dkr.ecr.<AWS_REGION>.amazonaws.com/demo:1.0.0",
            "docker_args": "-p 8080:80",
            "env_file": "",
            "command": "",
            "pre_condition": "test -x /usr/local/bin/docker-credential-ecr-login"
        }
    ]
}

Remember to change the AWS_ACCOUNT id and AWS_REGION to values relevant to your deployment. Also note that we check for the existence of the docker credentials helper as a pre-condition for the docker deployment to be executed. Also note that we do not setup any container registry authentication as docker is already configured to use credsStore in /root/.docker/config.json.

Conclusion

This tutorial shows how you can set up Docker deployments using Qbee and AWS ECR registry. It also serves as a blueprint for other docker registries that doesn't support a straight docker login. The configuration shown here can be associated with Qbee groups, tags or singular device for maximum flexibility.