🏗️
AWS CloudShellのDockerでもAWS CLIしたい
AWS の CloudShell が Docker をサポートしてました。
これで CloudShell 上でコンテナの動作確認もヨシ!と思ったら
認証情報がない?
# 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".
よく分からんけど動いてるからヨシ!
うそです。解説は後ほど
CloudShell 上の一時認証情報を取得して(丸っとコピー)
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] | .[]")
コンテナに環境変数として渡して実行する
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
※public.ecr.aws/aws-cli/aws-cli s3 lsは環境にあわせて変えてください
と動きました
後片付け
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
なんで動くの?
CloudShell は環境変数(トークン)をもとにして、メタデータから一時的な認証情報を取ってきて権限を得てます。
CloudShellでこんなコマンド叩くと認証情報が取得できる
curl \
-H "Authorization: $AWS_CONTAINER_AUTHORIZATION_TOKEN" \
-v $AWS_CONTAINER_CREDENTIALS_FULL_URI
コンテナの中からはこの認証情報を取得する仕組みが使えないので、ただ動かすとUnable to locate credentials.となります。
代わりにコンテナの外で取得して、環境変数としてコンテナに渡してあげることで認証情報を使えるようにしてます。
ちなみに認証情報を取得するトークンを渡すことも可能ですが、メタデータのエンドポイントと通信できなかったので諦めました
トークンを渡してもダメ
$ 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"
参考
Discussion