ECR repository migration
Another week another challenge to accomplish. This time I am working on migrating ECR repositories into other AWS region.
To give a background AWS ECR is like docker hub, but for AWS. It is a highly available and scalable architecture to securely store your internal docker files used in your organization.
By default, AWS does not allow you to do that via console or API’s. So I decided that this would be a nice challenge to take on and conquer. Today I will be writing a bash script to do the migration from one region to another.
Firstly, let's gather the requirements:
- Basic knowledge of working with AWS, ECR and docker
- Linux distro with python3 and pip3 installed
- Install docker in the distro
- Install jq, It is a JSON parser for the CLI
- Have an AWS account with permissions to push images to ECR and to get authorization token. Once the account is ready, have the AWS Access Key and Secret Access key ready.
- Install awscli via pip3 and run
aws configure. It will prompt for the Access Key, Secret Access key and region. Enter the region as the source region where your repository exists
Once all those requirements are done, the next thing to do is authenticate docker to use ECR. By default, docker can pull public images from docker hub without any authentication, but this is not the same story with ECR as docker need to log in with ECR to pull or push images.
In the terminal of your Linux distro, enter the following command
aws ecr get-login --region <source region>
aws ecr get-login --region <destination region>You need to run twice as ECR repositories are independent across regions. The above command will give an output of the format
docker login -u AWS -p <Some password> https://<account id>.dkr.ecs.<region>.amazonaws.com
Copy the command, paste and run in terminal. If everything is correct you should get the message Login Succeded
Now we are half way through, the next step is to write the bash script
#!/bin/bash
REPOSITORIES=$(aws ecr --region=$1 describe-repositories | jq -r 'map(.[] | .repositoryName ) | join(" ")')for repo in $REPOSITORIES; do
aws ecr --region $2 create-repository --repository-name $repo
TAGS=$(aws ecr --region $1 list-images --repository-name $repo | jq -r 'map(.[] | .imageTag) | join(" ")')
for tag in $TAGS; do
docker pull $3.dkr.ecr.$1.amazonaws.com/$repo:$tag
echo "Pull complete"
docker tag $3.dkr.ecr.$1.amazonaws.com/$repo:$tag $3.dkr.ecr.$2.amazonaws.com/$repo:$tag
echo "Tag complete"
docker push $3.dkr.ecr.$2.amazonaws.com/$repo:$tag
echo "Push complete"
done
done
The above script is the one that does all the magic. Before running this let me explain what the script is doing
- We are getting all the repository names from the source region and we iterate over them one at a time
- Using the repository name, we create a repository with the same name in the destination region
- Next, we go and fetch the image tags from each repository (Note that I am only copying tagged images)
- Once I have the tags, I use that to pull the image from the source region of ECR using
docker pull - Once the image is pulled and is stored in my local repository, I add it a tag of the destination repository so that when it is pushed it goes to the destination region
- Once tagging is done, I am pushing it to the destination repository and that is it, with a simple bash script I was able to copy images from one region to another
Finally, save the script in a .sh file and give it executable permissions. Run the following command to execute the script by replacing the values enclosed in <>
./<filename>.sh <source-region> <destination-region> <aws account id>
Here,
filename = Name of the script
source-region = Source AWS region
destination-region = Destination AWS region
aws account id = Account ID associated with the repositories
