AssumeRole(スイッチロール)で一時クレデンシャルを取得して環境変数にセットするワンライナー

2020.09.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部の若槻です。

今回は、AWS CLIでAssumeRole(スイッチロール)により一時クレデンシャルを取得して環境変数AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKENにセットしてAWS接続時の認証に利用可能とするワンライナーを作ってみたのでご紹介します。

前提

AWSプロファイルが次の通り設定済みであること。(Assume先プロファイルのmfa_serialは必要な場合のみ)

~/.aws/config

[default]
region=ap-northeast-1
output=json

[profile <Assume先プロファイル名>]
region = ap-northeast-1
mfa_serial = arn:aws:iam::xxxxxxxxxxxx:mfa/hoge
role_arn = arn:aws:iam::yyyyyyyyyyyy:role/fuga
source_profile = default

~/.aws/credentials

[default]
aws_access_key_id = XXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYY

設定方法は次の記事が参考になります。

ワンライナー

すみません、ワンライナーではないです。

まず~/.aws/configで定義したAssume先のプロファイル名を変数に指定します。

target_profile=<Assume先プロファイル名>

ここからIAMユーザーでMFA設定が有効/無効のいずれであるかにより使うワンライナーが異なります。

MFAが無効の場合

次のワンライナーを実行します。

AWS_STS_CREDENTIALS=`aws sts assume-role \
  --profile default \
  --role-arn $(aws configure get ${target_profile}.role_arn) \
  --role-session-name ${target_profile}-session`; \
export AWS_ACCESS_KEY_ID=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.AccessKeyId'`; \
export AWS_SECRET_ACCESS_KEY=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SecretAccessKey'`; \
export AWS_SESSION_TOKEN=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SessionToken'`

MFAが有効の場合

MFAデバイスから取得した6桁のMFAコードを変数に指定します。

mfa_code=<6桁のMFAコード>

次のワンライナーを実行します。

AWS_STS_CREDENTIALS=`aws sts assume-role \
  --profile default \
  --role-arn $(aws configure get ${target_profile}.role_arn) \
  --role-session-name ${target_profile}-session \
  --serial-number $(aws configure get ${target_profile}.mfa_serial) \
  --token-code $mfa_code`; \
export AWS_ACCESS_KEY_ID=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.AccessKeyId'`; \
export AWS_SECRET_ACCESS_KEY=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SecretAccessKey'`; \
export AWS_SESSION_TOKEN=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SessionToken'`

するとAssumeRoleにより取得された一時クレデンシャルの情報が環境変数AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYおよびAWS_SESSION_TOKENにセットされます。

あとはAWS CLI、AWS CDKや各種AWS SDKなどで環境変数にセットされたクレデンシャルを利用してAWSにアクセスするだけです。

ハマった箇所

当初クレデンシャル情報はAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYのみセットすれば良いと考えていましが、その状態でAWS CLIコマンドを実行した場合は、

An error occurred (InvalidAccessKeyId) when calling the <OperationName> operation: The AWS Access Key Id you provided does not exist in our records.

というエラーが発生しました。ドキュメントによると認証に一時クレデンシャルを使用する場合はAWS_SESSION_TOKENの指定が必要とのことです。

また、AWS_SECURITY_TOKENに古い一時クレデンシャルの情報が残っていた場合もエラーとなりハマりました。詳細は次の記事を参照ください。

おわりに

AWS CLIでAssumeRole(スイッチロール)により一時クレデンシャルを取得して環境変数AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKENにセットしてAWS接続時の認証に利用可能とするワンライナーを作ってみました。

AWSを扱う場合はAssumeRoleにより取得したクレデンシャル情報を自作スクリプトやaws-vaultにより環境変数にセットする場合が多いと思いますが、今回の方法はワンライナーを実行するだけなので余計なものを開発環境に入れたくない場合に便利だと思います。

参考

以上