この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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が簡単にできます。
.bash_profile
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もやはり便利ですね。