2016-12-09 14:15 追記
EC2 上の Docker コンテナ内からでも、AWS_
環境変数を設定することなくインスタンスプロファイルが使えました。
AWS SDK は AWS_*
環境変数設定されてなかったら自動で http://169.254.169.254/latest/meta-data/...
を叩いてクレデンシャルを取りに行きます。で、ホスト直実行でもコンテナ挟むのでもつなぎに行くネットワークは同じ AWS なので問題なくインスタンスプロファイルを取れるのでした。
したがって、この記事に書いてあるような手間をかける必要はありません…
tl;dr
AWS_SECURITY_TOKEN
AWS_SESSION_TOKEN
を忘れるな
2019-03-11 追記
awscli は AWS_SECURITY_TOKEN
で実行できますが、 AWS SDK は AWS_SESSION_TOKEN
でないと動作しないものがあるようです。
ログイン画面から発行されるワンタイムパスワードも現在は AWS_SESSION_TOKEN
であるため、そちらに統一する方が良さそうです。
時代は IAM Role
EC2 上で AWS リソースにアクセスする場合、専用の IAM ユーザを作ってクレデンシャルを発行してもいいのですが、IAM Role を EC2 に紐付けると便利です。クレデンシャルをアプリケーションコードやスクリプトに埋め込む必要がなくなるからです。
しかし awscli や AWS SDK を埋め込んだコードを__ホスト上で直に__実行する場合は彼らがよしなにクレデンシャルを取得するのでいいのですが、Docker コンテナ上で実行する場合は少々面倒です。-e AWS_ACCESS_KEY_ID=
でクレデンシャルを渡したいのですが値はどこから取ればいいのか。
※ 今回は ECS 上ではなく1、直接インスタンス上で docker run
する場合の話です。
metadata からクレデンシャルを取り出す
EC2 インスタンス内部から http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>
を叩くと、いま現在有効なクレデンシャルが得られます。これを jq
なりでパースして値だけ抜き出せばそのまま使えます。Expiration
の時刻になったらクレデンシャルは入れ替わります。
core@ip-10-0-2-126 ~ $ curl -w '\n' http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>
{
"Code" : "Success",
"LastUpdated" : "2016-10-03T09:13:16Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "awsaccesskeyid",
"SecretAccessKey" : "awssecretaccesskey",
"Token" : "SecretToken",
"Expiration" : "2016-10-03T15:26:54Z"
}
ただ、このクレデンシャルを使うには AccessKeyId
(= AWS_ACCESS_KEY_ID
) と SecretAccessKey
(= AWS_SECRET_ACCESS_KEY
) だけ抜き出すのでは足りません Token
(= AWS_SECURITY_TOKEN
) も一緒にアプリケーション / スクリプトへ渡してあげる必要があります。
シェルスクリプトにするとこういう感じです (curl, jq 前提)。
#!/bin/bash
metadata=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>/)
export AWS_ACCESS_KEY_ID=$(echo $metadata | jq -r .AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $metadata | jq -r .SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $metadata | jq -r .Token)
docker run \
--rm \
-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 \
awesome:latest
自分はこれで数時間ハマったので、今後同じことをする人の助けになれば幸いです。
REF
-
ECS は Task 単位で IAM Role を紐付けられるので便利 ↩