STSで一時クレデンシャルを発行する
Switch Role先の環境で作業はしたい。だけど、アクセスキーを発行しないとツールが使えない。Switch Role先の環境でIAM ユーザを作るわけにもいかない...。
こんな感じで困ったことありませんか。そんな時にAWS STSを知っていればなんとか対処できます。自分が手間取ったのでどう対処したかを書きます。
STSとは
AWS Security Token Serviceの略称で、一時的な認証情報を発行します。
発行される認証情報は、「アクセスキー」、「シークレットキー」、「セッショントークン」の3つが発行されます。
スイッチロールの際にもSTSを使用してスイッチ先の各種リソースにアクセスしてるので、認証情報さえ取り出せばうまいことアクセスキーが使えそうですね。
Assume Role
読んで字のごとく、IAM Roleの権限を引き受けます。STSのこれを呼び出せば、認証情報が取得できます。
図にするとこのような流れで一時クレデンシャルを発行します。
- 権限を引き受けるIAM Userで assume-roleをコールする
- 2つのアカウントで問題なく権限を委任できるかを確認する
- STSから一時クレデンシャルが発行され、レスポンスが返ってくる
どうやって一時クレデンシャルを受け取るかをわかったところで、aws cliを使って実際に取得してみましょう。
$ aws sts assume-role \ --role-arn arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxx \ # スイッチ先のIAM RoleのARN --role-session-name foo-bar-session \ # セッション名 自由に指定できる --duration-second 900 \ 一時クレデンシャルの有効期限 900秒以上 --profile foo-bar # assume-role をコールするユーザ情報
先ほどの図に当てはめると role-arn
は、アカウントBのIAM Roleを割り当てて、 profile
にはアカウントAのIAMユーザのプロファイル指定します。
MFAが必須の環境の場合は、MFAデバイスのARNとMFAトークンを追加してコマンドを実行します。
$ aws sts assume-role \ --role-arn arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxx \ --role-session-name foo-bar-session \ --duration-second 900 \ --profile foo-bar \ --serial-number arn:aws:iam::xxxxxxxxxxxx:mfa/xxxxxxxxxxxx \ # MFAデバイスのARN --token-code 123456 # MFAで発行される6桁のトークン
あとは、返ってきたレスポンスを元に環境変数としてエクスポートすれば、アクセスキーを用いてのAWSリソースへのアクセスが可能になります。
.bash_profileに登録する
assume-roleは確かに便利ですけど、毎回実行するのは大変です。なので、bash_profileに一時クレデンシャルを呼び出せる関数を登録しましょう。
jq
を事前にいれたmac上での動作はすると思います。mac以外なら最後のpbcopy
をしなければ動くとは思います。
関数上部の環境変数はよしなに設定してください。 関数をよびだして、MFAトークンを入力して、貼りつけてエンターを押せば、assume-roleが簡単にできます。
function foo_assume { ROLE_ARN='arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxx' SERIAL_NUMBER='arn:aws:iam::xxxxxxxxxxxx:mfa/xxxxxxxxxxxx' SOURCE_PROFILE='xxxxxxxxxxxx' DATE=`date +%s` read -sp "Input MFA Code: " TOKEN_CODE OUTPUT=`aws sts assume-role \ --role-arn ${ROLE_ARN} \ --serial-number ${SERIAL_NUMBER} \ --role-session-name ${DATE}-session \ --profile ${SOURCE_PROFILE} \ --duration-second 1800 \ --token-code ${TOKEN_CODE} ` AWS_ACCESS_KEY_ID=`echo $OUTPUT | jq .Credentials.AccessKeyId` AWS_SECRET_ACCESS_KEY=`echo $OUTPUT | jq .Credentials.SecretAccessKey` AWS_SESSION_TOKEN=`echo $OUTPUT | jq .Credentials.SessionToken` echo "" echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" echo "export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" echo "export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" echo "Ctl P makes you Happy..." echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID && export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY && export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" | pbcopy }
最後に
これで、アクセスキーが必要なツールでも何とか使えそうになりました。
AWSの利便性もさることながらBashもやはり便利ですね。