How to correctly log in to AWS Elastic Container Registry on Windows command line

How to correctly log in to AWS Elastic Container Registry on Windows command line

; Date: Sun May 10 2020

Tags: Amazon Web Services »»»» AWS ECR

The Elastic Container Registry (ECR) is a Docker container registry for use while deploying containers to AWS ECS. It is convenient and relatively easy to use. AWS helpfully supplies command strings to log in to ECR from the command line so you can publish container images with docker push. But the supplied command line for Windows doesn't work right, and needlessly relies on a tool that seems to not be very useful.

In my case, I am normally using a macOS laptop and have used Unix systems for decades. I use Windows, primarily so that my books have correct advice for use on Windows. I'm currently updating my book Node.js Web Development to include information about deploying Docker-based Node.js services to AWS ECS, and of course this includes pushing container images to ECR. Which then means being able to log in to ECR at the command line.

The PowerShell command that AWS tells us to use simply does not work, even when you install the AWS Tools for PowerShell. Instead what works is an amalgam of the command suggested for Unix-like systems, and the Windows syntax for accessing environment variable values.

On Unix-like systems this is fairly simple:

aws ecr get-login-password --region $AWS_REGION | \
    docker login --username AWS --password-stdin $AWS_USER.dkr.ecr.$AWS_REGION.amazonaws.com

I've added environment variables so that this can be tailored for any account, and any region. The aws ecr command retrieves a password token, that's piped into docker login. On Unix-like systems this is fast and easy.

For Windows, this is suggested:

(Get-ECRLoginCommand).Password | \
    docker login --username AWS --password-stdin $AWS_USER.dkr.ecr.$AWS_REGION.amazonaws.com

This is similar, but it uses a PowerShell command of some sort to retrieve the password string. The problem with this is the command doesn't work.

The first issue is that Get-ECRLoginCommand might not be "recognized as the name of a cmdlet, function, script file, or operable program". There's a note that this requires the AWS Tools for PowerShell, but there's no link on where that is, how to install it or anything. After some searching that tool is found on the AWS website, and an installer is available. ( (aws.amazon.com) here) Why is it so much trouble for AWS to create good quality documentation? Why does their documentation always leave out important details?

This tool is easily installed but ... running Get-ECRLoginCommand doesn't work well, in that it pauses for a looooong time, doesn't do anything, and you cannot kill the command with CTRL-C and instead you have to close the PowerShell window.

What I found is that this works on Windows:

aws ecr get-login-password --region $AWS_REGION 

Meaning, it runs and prints out a password string. That's what would be expected since it is the same command that we run on Unix-like systems. Why did the AWS people want us to use this other thing? Therefore you can pipe that into a docker login and get it working.

After some experimenting, I found this to work:

$env:AWS_REGION = "us-west-2"
$env:AWS_USER = "09E1X6A8MPLE"
$env:AWS_PROFILE = "profile-name"
aws ecr get-login-password --region %AWS_REGION% | \
    docker login --username AWS --password-stdin %AWS_USER%.dkr.ecr.%AWS_REGION%.amazonaws.com

The first three lines set PowerShell environment variables with the required values. The first is the region code to use. The second is the numeric user ID for the IAM account you are using. The last is the AWS Profile name you're using.

The %VAR_NAME% notation is the Windows way to access an environment variable. The result is the same as the Unix command like, but interpolated for the way Windows users access environment variables.

Being a fan of automation, and of Node.js, I present this package.json that records some scripts:

{
    "name": "terraform-aws",
    "description": "Scripts to build and manage AWS infrastructure",
    "scripts": {
        "docker-login": "aws ecr get-login-password --profile $AWS_PROFILE --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_USER.dkr.ecr.$AWS_REGION.amazonaws.com",
        "docker-logout": "docker logout $AWS_USER.dkr.ecr.$AWS_REGION.amazonaws.com",
        "docker-login-windows": "aws ecr get-login-password --region %AWS_REGION% | docker login --username AWS --password-stdin %AWS_USER%.dkr.ecr.%AWS_REGION%.amazonaws.com",
        "docker-logout-windows": "docker logout %AWS_USER%.dkr.ecr.%AWS_REGION%.amazonaws.com",
        "ecr-repositories": "aws ecr describe-repositories",
    }
}

This is part of a larger project to demonstrate using Terraform to deploy to AWS ECS. In any case we see a pair of scripts, for Unix-like systems and for Windows. It's the same commands each time, with the same environment variables, but requiring different syntax because of how this works on Windows and on the rest of the computing world.

We can add other scripts - for example the aws ecr describe-repositories command shown here. This command consults environment variables to find the AWS Profile, AWS Region, etc, to govern where it will look for the repositories to describe. Therefore we don't have to supply command parameters for those values, they can come from the environment.

About the Author(s)

(davidherron.com) David Herron : David Herron is a writer and software engineer focusing on the wise use of technology. He is especially interested in clean energy technologies like solar power, wind power, and electric cars. David worked for nearly 30 years in Silicon Valley on software ranging from electronic mail systems, to video streaming, to the Java programming language, and has published several books on Node.js programming and electric vehicles.

How to correctly log in to AWS Elastic Container Registry on Windows command line