Working with AWS in devcontainers

4 minute read

If AWS is part of your stack, you will eventually want to configure your devcontainers to work with Amazon’s services.

Sharing credentials

When working with AWS on your local machine, one of the worst practices that should be always avoided is providing credentials via environmental variables or, even worse, via configuration files.

The preferred approach is using the shared AWS credentials file. This file is bound to your profile and can be used by all AWS SDKs and toolkits.

By default, thsi file is located in the .aws directory within the user’s home directory and is named credentials.

Here is how this file looks like

[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

We can leverage this file to share the credentials to our devcontainers.

At first, we could be tempted to copy the file in the container while we are building it. The problem with this approach is that the credentials would be part of the container image and be available to everyone who can access this image.

A safer approach is to use mount points so that a certain path of the container is actually pointing at a portion of the file system of the host system.

Normally, you would instruct Docker when executing the docker run command but this isn’t possible when working with devcontainers as Visual Studio Code takes care of launching the container.

Instead, we can use the devcontainer.json file to describe the container we want to Visual Studio Code.

Specifically, we can use the mounts section to describe a mount point to be attached to the container when launched.

"mounts": [
    "source=${env:HOME}${env:USERPROFILE}/.aws,target=/root/.aws,type=bind"
]

The command is pretty straight forward. It is divided in three parts

  • source: this section points to the local folder we will use
  • target: this section points where we should add the mount point
  • type: the type of the mount, in this case it’s always bind

In the snippet above, the source fragment accepts either $HOME (supported in Linux and MacOS systems) or $USERPROFILE (supported in Windows).

Adding the snippet above to the devcontainer.json and letting Visual Studio Code rebuild the container image will make the AWS credentials available also to tools and SDKs used in the container.

You can test that everything worked fine by running this command in the terminal available in Visual Studio Code.

$ cat /root/.aws/credentials

If everything is correctly in place, you’ll see the content of your credentials file.

[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

This setup is enough to locally run your AWS-enabled applications: the SDK will use the shared credentials to sign the requests of your application.

Installing the AWS CLI

Once you got your credentials configured for the container, you might want to use the AWS CLI to perform operations on AWS services.

To make sure that this tool is installed at every restart of the container, we can modify the Dockerfile by appending the following line:

RUN apt-get update && apt-get -y install --no-install-recommends awscli

This line instructs Docker to use apt-get to install awscli, the package containing the AWS CLI.

Unfortunately, some configurations (like the one used for .NET Core applications) require some extra setup.

If that is the case, it’s sufficient to add the following line just before

ENV TZ=Europe/Stockholm
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

These lines simply configure the timezone for the container.

Once you have saved the modifications to the Dockerfile, simply rebuild the container and you should be able to use the AWS CLI.

You can test this by simply running the command aws in the terminal

$ aws
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: the following arguments are required: command

Installing the AWS Toolkit for Visual Studio Code

Personally, I don’t use the AWS Toolkits a lot but they are a convenient way to interact with AWS services from within the IDE (like Visual Studio) or text editor (like Visual Studio Code) of choice.

To install the toolkit as an extension of the instance of Visual Studio Code running in the container, we can simply register it in the devcontainer.json.

"extensions": [
    "amazonwebservices.aws-toolkit-vscode"
],

Once you have saved and rebuilt the container, you’ll notice the AWS logo in the Activity Bar of Visual Studio Code. From there, you can open the Sidebar panel related to AWS.

The Sidebar panel gives you the possibility to interact with some of the services like Lambda, S3, CloudWatch and CloudFormation and so on.

Recap

In this post we have seen how to share your AWS credential file with a devcontainer.

With the container able to access the AWS services, we saw how to install the AWS CLI and the AWS Toolkit for Visual Studio Code.