AWS CLI Multi Factor Auth (MFA) with Docker

Recently I blogged about using SAM Cookicutter Projects to kickstart your development. One aspect of that work was leveraging Docker containers for all the SAM CLI commands. However, sometimes we all have AWS CLI tasks that fall outside a project. At Custom Ink we make heavy usage of Homebrew and projects like pyenv, a Python Version Manager, to install both system and project-scoped tooling. Neither of which help me maintain a sane global AWS CLI setup. Especially when multi factor authentication is needed.

đŸšĸ Thanks AWS Docker CLI

Recently the AWS Docker CLI project announced CLI v2 support. This is a very lightweight container which delegates all run commands to the aws entrypoint which is already pre-installed. I've never used the Docker CLI project and today felt like a good time to switch. So I make a shell function (this could be a long alias too) called dk-aws and aliased it to aws.

function dk-aws() {
  AWS_PROFILE=${AWS_PROFILE:=default}
  docker run \
    --interactive \
    --tty \
    --rm \
    --env AWS_PROFILE=$AWS_PROFILE \
    --volume "${HOME}/.aws:/root/.aws:delegated" \
    --volume "${PWD}:/aws:delegated" \
    "amazon/aws-cli" \
    $@
}

alias aws=dk-aws

Here is a simple usage example. I would imagine that this would serve most everyone's AWS CLI needs. What a joy!

$ aws s3 ls
2010-01-26 16:33:21 cdn.metaskills.net
2020-03-16 00:38:38 cookiecutter-ruby-demo-c945wcad59
2020-01-13 03:00:38 homemarks.com

🔐 Multi Factor CLI

Recently I adopted some better security practices and began using MFA with my AWS CLI. Specifically, I had installed this aws-mfa project which allows me to dynamically generate a profile that has temporary credentials. So how to make that work with the Docker CLI usage above? Here are a few hacks I quickly put together this morning. First, a Dockerfile is needed to build a custom image using the amazon/aws-cli image above as the base. This Dockerfile can be located anywhere on your computer, mine is in my ZSH kit's resources folder at ~/.zshkit/resources/Dockerfile-aws-mfa.

FROM amazon/aws-cli
RUN cd /tmp && \
    curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" && \
    python get-pip.py && \
    pip install aws-mfa

To build and name this image, I use this function. Notice how we leverage the --tag option to get a handle on the image name.

function dk-aws-mfa-build() {
  file="${HOME}/.zshkit/resources/Dockerfile-aws-mfa"
  docker build --tag "metaskills/aws-cli" - < $file
}

Now when I need to setup my CLI to leverage temporary MFA credentials, I invoke this aws-mfa function below. Change the --profile value as needed to best meet your naming strategy. Most important, have a great time using the AWS CLI via Docker from now on. 😀

function aws-mfa() {
  docker run \
    --interactive \
    --tty \
    --rm \
    --volume "${HOME}/.aws:/root/.aws:delegated" \
    --volume "${PWD}:/aws:delegated" \
    --entrypoint "/usr/bin/aws-mfa" \
    "metaskills/aws-cli:latest" \
    --profile=production
}

📚 Resources

by Ken Collins
AWS Serverless Hero