iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🏗️

Using AWS CLI in Docker Containers on AWS CloudShell

に公開

https://aws.amazon.com/jp/about-aws/whats-new/2024/01/aws-cloudshell-docker-13-regions/

AWS CloudShell now supports Docker.
I thought, "Now I can test containers on CloudShell too—all set!" but then...

No credentials?
# Run in a container on CloudShell
~ $ docker run -it public.ecr.aws/aws-cli/aws-cli s3 ls

Unable to locate credentials. You can configure credentials by running "aws login".

I don't really get it, but it works, so we're good!

Just kidding. I'll explain later.

Get temporary credentials on CloudShell (Copy and paste the whole thing)
eval $(curl -s -H "X-aws-ec2-metadata-token: $AWS_CONTAINER_AUTHORIZATION_TOKEN" $AWS_CONTAINER_CREDENTIALS_FULL_URI \
     | jq -r "[\"export AWS_ACCESS_KEY_ID=\" + .AccessKeyId, \"export AWS_SECRET_ACCESS_KEY=\" + .SecretAccessKey,\"export AWS_SESSION_TOKEN=\" + .Token] | .[]")
Run by passing environment variables to the container
docker run \
  -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
  -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
  -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \
  public.ecr.aws/aws-cli/aws-cli s3 ls

*Please change public.ecr.aws/aws-cli/aws-cli s3 ls according to your environment.

And it worked!

Cleanup
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN

Why does it work?

CloudShell uses environment variables (tokens) to fetch temporary credentials from metadata to gain permissions.

You can obtain credentials by running this command in CloudShell
curl \
  -H "Authorization: $AWS_CONTAINER_AUTHORIZATION_TOKEN" \
  -v $AWS_CONTAINER_CREDENTIALS_FULL_URI

Since the mechanism for retrieving these credentials cannot be used from within a container, running it directly results in Unable to locate credentials.

Instead, we retrieve them outside the container and pass them as environment variables to make the credentials available inside the container.

By the way, it is possible to pass the token for retrieving credentials, but I gave up because I couldn't communicate with the metadata endpoint.

Passing the token doesn't work either
$ docker run \
>   -e AWS_CONTAINER_AUTHORIZATION_TOKEN=$AWS_CONTAINER_AUTHORIZATION_TOKEN \
>   -e AWS_CONTAINER_CREDENTIALS_FULL_URI=$AWS_CONTAINER_CREDENTIALS_FULL_URI \
>   public.ecr.aws/aws-cli/aws-cli s3 ls

Error when retrieving credentials from container-role: Error retrieving metadata: Received error when attempting to retrieve container metadata: Could not connect to the endpoint URL: "http://localhost:1338/latest/meta-data/container/security-credentials"

References

https://qiita.com/moritalous/items/8a548ce1743b0b4f8b6d
https://dev.classmethod.jp/articles/temporary-aws-access-via-cloudshell-export-credentials/
https://repost.aws/ja/knowledge-center/codebuild-temporary-credentials-docker
https://docs.aws.amazon.com/cloudshell/latest/userguide/tutorial-presigned-url.html
https://docs.docker.jp/machine/drivers/aws.html

Discussion