This T.I.L. note deals with topic of Docker Registry credentials/authorization options when you use AWS Elastic Beanstalk (EB) as a Multicontainer Docker. If you need more info check this article or FAQ links bellow.

3rd party Docker registry provider

I’m placing this here just to show difference of setup between 3rd party Docker Registry and native AWS Docker Registry (ECR)

If you use Dockerhub or Quay.io as your Docker registry you need to place “authentication” block in your Dockerrun.aws.json. Inside that you provide the S3 bucket (bucket) from which the EB agent pull a file (key) during deployment.

# Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": 2,
  "authentication": {
    "bucket": "mybucketfullofsecrets",
    "key": "dockercfg-myawesomeapp"
  },
  "containerDefinitions": [
     {
       "name": "rails",
       "image": "myawesomecompany/myawesomesecretproject:latest",
       # ...
     }
   ]
}

You need to make sure that EB instance can access to the bucket, and instance is able to download the credential file (Grant permissions for the s3:GetObject operation to the IAM role in the instance profile) and bucket needs to be in same region as EB.

Full steps are out of the scope for this T.I.L. note Further information can be found here: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker.container.console.html#docker-images-private

Credential file dockercfg-myawesomeapp looks something like this:


{
  "auths" :
  {
    "https://index.docker.io/v1/": {
      "auth" : "auth_token",
      "email" : "email"
    },
    "quay.io": {
      "auth": "dGrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrN3",
      "email": "[email protected]"
    }
  }
}

This file is similar to your local ./docker/config.json

AWS EC2 Container Registry

AWS has a Docker Registry product ECR. When configuring it with your EB you don’t need to provide the authentication block in your Dockerrun.aws.json and no upload of credentials to S3 bucket.

In fact I found out that if I do all the other remaining steps for ECR but still leave the authentication section in my Dockerun.aws.json then docker pull from ECR is not working !

{
  "AWSEBDockerrunVersion": 2,
  "containerDefinitions": [
     {
       "name": "rails",
       "image": "666666666666.dkr.ecr.eu-west-1.amazonaws.com/myawesomesecretproject:latest",
       # ...
     }
   ]
}

Only thing you need to do is to allow your EB “instance profile role” to has AmazonEC2ContainerRegistryReadOnly policy

Steps:

step 1 - Create AWS ECR docker Registry
AWS Web console > EC2 Container Service (ECS) > Repositories > Create repository

Note: you need to create it in same AWS region as EB

step 2 - To find out What is “instance profile role” for my EB Environment
AWS Web console > Elastic Beanstalk > Your environment > Configuration > Instances > Instance profile (that's the value)


e.g.: aws-elasticbeanstalk-ec2-role
step 3 - To add AmazonEC2ContainerRegistryReadOnly policy
AWS Web console > IAM > Roles > Role (e.g. aws-elasticbeanstalk-ec2-role) > Attach policy >  AmazonEC2ContainerRegistryReadOnly 
step 4 - Add access inside the ECR

Although the official EB ECR is not saying this, you may need to “allow” the instance profile on the ECR side too

AWS Web console > EC2 Container Service (ECS) > Repositories > Repository (e.g. myawesomesecretproject) > permissions

…add add a permission from the webinterface tool. Search for your EB role (e.g.: aws-elasticbeanstalk-ec2-role) and add all read only permissions to the Repository

Build & push to ECR

Give you want to build and push your docker image on from your laptop

via AWS CLI you need to run:

aws ecr get-login --no-include-email

Credentials in your laptop must have permissions for ECR

and run the output of that command

docker login -u AWS -p xxxxxxxxxxxxxxxxxxxxxx  https://666666666666.dkr.ecr.eu-west-1.amazonaws.com

this will add an authorization entrie to your ~/.docker/config.json for ECR registry

Now you are able to build and push


docker build -t=666666666666.dkr.ecr.eu-west-1.amazonaws.com/myawesomesecretproject:latest .
docker push 666666666666.dkr.ecr.eu-west-1.amazonaws.com/myawesomesecretproject:latest
docker pull 666666666666.dkr.ecr.eu-west-1.amazonaws.com/myawesomesecretproject:latest

Now be careful now. It seems that the credential details generated by aws ecr get-login expire in some time.

To do it for each deployemnt you need to provide Elasticbeanstalk deployment hook

cat  .ebextensions/91_login_to_aws_ecr.config
commands:
  20_login_to_aws_ecr_before_pull:
    command: sudo $(sudo aws ecr get-login --no-include-email )

note by using backtick execution you can potentionaly introduce security risk to your build machine as you will execute whatever the aws ecr command returns. Feel free to alter this command in more secure way

Note

in the past I was setting the “login to ecr” with crontab

crontab -e
-0 * * * *  sudo -u ubuntu `aws ecr get-login`

if you have any dificulties with it try this solution