最近、複数の AWS アカウントで個別に IAM User を作成するのではなく、IAM User をまとめた AWS アカウントを1つ設けて、その他の AWS アカウントには IAM Role だけ作って Role の切り替えで運用するようにしてみました。
ロールの切替
マネジメントコンソールで操作するときは画面右上のユーザー名が表示されたところから切り替えができます。
AWS CLI は、.aws/credentials
を次のように記述し、--profile bar
のようにプロファイル名をオプションにつければ OK です(もしくは AWS_DEFAULT_PROFILE
環境変数)。
.aws/credentials
; スイッチする元
[foo]
; アクセスキー
aws_access_key_id = AKI...
; シークレットキー
aws_secret_access_key = abc123...
; スイッチする先
[bar]
; スイッチする元のプロファイル名
source_profile = foo
; ロールの arn(アカウントナンバーとロール名)
role_arn = arn:aws:iam::999999999999:role/developer
AWS SDK でも、プロファイル名を SDK で指定するなり、AWS_PROFILE
環境変数を設定するなりすれば大丈夫です。
.
.
.
と、思っていたのですが、boto-2.38.0 だと AWS_PROFILE
環境変数を設定してもダメでした・・・
AWS SDK は .aws/credentials
に記述した source_profile/role_arn
によるロールの切り替えには未対応なのかな? それとも boto3 とかなら大丈夫なのかな?
AssumeRole で得たクレデンシャルを環境変数に入れる
AWS SDK は Ansible のダイナミックインベントリで boto をちょっと使っているだけで、それ以外はほとんど AWS CLI なので、とりあえず Ansible を実行するときは直前に下記を実行して AssumeRole して得られたクレデンシャルを環境変数に設定することにしました。
eval "$(aws sts assume-role --role-session-name oreore --profile foo \
--role-arn arn:aws:iam::999999999999:role/developer \
--query '[Credentials.AccessKeyId, Credentials.SecretAccessKey, Credentials.SessionToken]' \
--output text | (
read AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN
export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN
declare -p AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECURITY_TOKEN))"
direnv の .envrc に仕込む
direnv の .envrc
に↑を仕込もうとするとなぜか上手く変数が設定されませんでした(謎)。
ので、.envrc
には次のように書いています。
credentials=($(aws sts assume-role --role-session-name oreore --profile foo \
--role-arn arn:aws:iam::999999999999:role/developer \
--query '[Credentials.AccessKeyId, Credentials.SecretAccessKey, Credentials.SessionToken]' \
--output text))
export AWS_ACCESS_KEY_ID=${credentials[0]}
export AWS_SECRET_ACCESS_KEY=${credentials[1]}
export AWS_SECURITY_TOKEN=${credentials[2]}
これで、.envrc
の置いているディレクトリに cd すれば自動的にクレデンシャルが取得されて環境変数に設定されます。