Elastic Beanstalk Docker using AWS EC2 Container Registry (ECR)
Today I've Learned postThis 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
FAQ & related articles
- AWS Elastic Beanstalk Docker Rails example
- AWS EC2 Container Registry (ECR)
- http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker.container.console.html
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
Entire blog website and all the articles can be forked from this Github Repo