AWS CLI上からAssume Roleするスクリプトを作成してめんどくさい作業を自動化してみた
リテールアプリ共創部のるおんです。
特定のプロジェクトのCDKをデプロイする際に、CLI上からAssume Roleする必要がありました。CLIからのAssume Roleの仕方を調べていると、皆さんスクリプトを書いて自動化していることがわかったので参考に自分も作ってみました。
前提としてMFAを有効にしています。
スクリプトが何をしているのか、そもそもスクリプトを使用しないとどのような辛さがあるのかがわからなかったので記事にして解説してみました。
結論だけ見たい方は、自動化したスクリプトと使ってみるを先にご覧ください。
CLIから手動でAssume Roleしてみる
まずは、コマンドを打って手動でAssume Roleしてみます。この方法では大変手間がかかり、辛さを実感できると思います。 以下では、その手順を詳細に説明します。
Assume Role手順
1. プロファイル情報の確認
まず、~/.aws/config
ファイルを開いて、使用するプロファイルの情報を確認。
[default] region = ap-northeast-1 output = json [profile my-profile] role_arn = arn:aws:iam::xxxxxxxxxxxx:role/my-role mfa_serial = arn:aws:iam::xxxxxxxxxxxx:mfa/my-mfa-device source_profile = default region = ap-northeast-1
2. MFAコードの取得
MFAデバイスから6桁のMFAコードを取得。
3. AWS CLIを使用して一時的な認証情報を取得
aws sts assume-role
コマンドを手動で実行。以下はその例です。各オプションはそれぞれ置き換えてください。
$ aws sts assume-role \ --role-arn arn:aws:iam::xxxxxxxxxxxx:role/my-role \ --serial-number arn:aws:iam::xxxxxxxxxxxx:mfa/my-mfa-device \ --role-session-name my-session \ --profile default \ --duration-seconds 43200 \ --token-code ${取得したMFAコード} \ --region ap-northeast-1
各オプションの説明
--role-arn
: Assume Roleを実行するためのIAMロールのARN。--serial-number
: MFAデバイスのARN。--role-session-name
: セッションの名前。任意の名前を指定可能。--profile
: 使用するAWS CLIプロファイル。このプロファイルに設定されている認証情報を用いてIAMロールを引き受けることができる。--duration-seconds
: セッションの有効期間(秒単位)。デフォルトだと1時間で、最大12時間(43200秒)まで指定することができます。--token-code
: MFAデバイスから取得した6桁のコード。--region
: AWSのリージョン。
このコマンドを実行すると、以下のようなJSON形式の出力が得られます。
取得したJSONに含まれる情報は、AWSから発行された一時的な認証情報です。これらの認証情報は、指定された期間にわたって有効です。
{
"Credentials": {
"AccessKeyId": "ASIAxxxxxx",
"SecretAccessKey": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"SessionToken": "zzzzzzzzzzzz",
"Expiration": "2024-5-17T12:34:56Z"
}
}
5. 取得した認証情報を環境変数に設定
取得した一時的な認証情報は、環境変数として設定することで、AWS CLIを使用してAWSリソースにアクセスする際に使用できます。
これらを手動で環境変数に設定。
$ export AWS_ACCESS_KEY_ID="ASIAxxxxxx" $ export AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" $ export AWS_SESSION_TOKEN="zzzzzzzzzzzz"
6. 正しく設定されているかを確認
$ aws sts get-caller-identity
正しくAssume Roleできているかを確認します。以上でCLI上でのAssume Roleをすることができました。
しかし、これをセッションが切れるたびに毎回やるのはめんどくさいですよね…。コマンドの入力ミスや、環境変数の設定ミスが発生しやすくなります。
というわけで、今回はこれを自動化するShellScriptをクラスメソッドの先輩方の記事を参考に作成してみました!
参考:
CLIから自動でAssume Roleする
自動化したスクリプト
以下のShellScriptをassume-role.sh
という名前で作成しました。
#!/bin/bash echo '\nProfile List:' grep "\[profile .*\]" ~/.aws/config echo '\nProfile?' read PROFILE echo 'MFA Code?' read TOKEN_CODE ROLE_ARN=`aws configure get role_arn --profile $PROFILE` SERIAL_NUMBER=`aws configure get mfa_serial --profile $PROFILE` SOURCE_PROFILE=`aws configure get source_profile --profile $PROFILE` REGION=`aws configure get region --profile $PROFILE` DATE=`date +%s` OUTPUT=`aws sts assume-role \ --role-arn ${ROLE_ARN} \ --serial-number ${SERIAL_NUMBER} \ --role-session-name ${DATE}-session \ --profile ${SOURCE_PROFILE} \ --duration-second 3600 \ --token-code ${TOKEN_CODE} \ ` if [ -z "$REGION" ]; then export AWS_DEFAULT_REGION='ap-northeast-1' echo 'ap-northeast-1' else export AWS_DEFAULT_REGION="$REGION" echo "$REGION" fi export AWS_ACCESS_KEY_ID=`echo $OUTPUT | jq -r .Credentials.AccessKeyId` export AWS_SECRET_ACCESS_KEY=`echo $OUTPUT | jq -r .Credentials.SecretAccessKey` export AWS_SESSION_TOKEN=`echo $OUTPUT | jq -r .Credentials.SessionToken`
以上が自動化したスクリプト全体です。このスクリプトは以下のように実行してください
使ってみる
$ . ./assume-role.sh Profile List: [profile my-profile] [profile hoge-profile] [profile piyo-profile] Profile? hoge-profile // ここで入力 MFA Code? 111111 // ここでMFAコードを入力 $ aws sts get-caller-identity // 正しく設定できているかを確認
超簡単にAssume Roleできました!以上でめんどくさいCLI上のAssumeRoleを自動化することができました。 それでは、先ほどのスクリプトを詳しくみていきます。
解説
このスクリプトについて簡単に解説します。
echo '\nProfile List:' grep "\[profile .*\]" ~/.aws/config echo '\nProfile?' read PROFILE
最初のこのセクションでは、~/.aws/config
ファイルからプロファイル名を抽出してリスト表示します。そして、この中から今回使用したいプロファイル名を要求し、入力されたものをPROFILE
変数に格納しています。
echo 'MFA Code?' read TOKEN_CODE
次に、ここではMFAの入力を求めて、それをTOKEN_CODE
変数に格納しています。
ROLE_ARN=`aws configure get role_arn --profile $PROFILE` SERIAL_NUMBER=`aws configure get mfa_serial --profile $PROFILE` SOURCE_PROFILE=`aws configure get source_profile --profile $PROFILE` REGION=`aws configure get region --profile $PROFILE` DATE=`date +%s`
指定されたプロファイルからロールARN、MFAシリアル番号、ソースプロファイル、リージョンを取得し、それぞれ変数に格納します。
OUTPUT=`aws sts assume-role \ --role-arn ${ROLE_ARN} \ --serial-number ${SERIAL_NUMBER} \ --role-session-name ${DATE}-session \ --profile ${SOURCE_PROFILE} \ --duration-second 3600 \ --token-code ${TOKEN_CODE} \ `
aws sts assume-role
コマンドを使用して、一時的なセッションを取得します。これは手動の時もやりましたね。その結果をOUTPUT変数に格納します。
if [ -z "$REGION" ]; then export AWS_DEFAULT_REGION='ap-northeast-1' echo 'ap-northeast-1' else export AWS_DEFAULT_REGION="$REGION" echo "$REGION" fi
リージョンを指定します。設定されていない場合は、デフォルトでap-northeast-1(東京リージョン)を使用し、設定されている場合は、そのリージョンを使用します。
export AWS_ACCESS_KEY_ID=`echo $OUTPUT | jq -r .Credentials.AccessKeyId` export AWS_SECRET_ACCESS_KEY=`echo $OUTPUT | jq -r .Credentials.SecretAccessKey` export AWS_SESSION_TOKEN=`echo $OUTPUT | jq -r .Credentials.SessionToken`
最後に環境変数を設定する作業です。
OUTPUT
変数から取得した一時的な認証情報をjqコマンドを使用して抽出し、環境変数に設定します。これにより、AWS CLIから一時的な認証情報を使用できるようになります。
今回私が実施した動作環境はMacOSですが、jqコマンドのインストールは環境ごとに異なるので、それぞれの環境での対応が必要です。 jq is a lightweight and flexible command-line JSON processor.
以上が今回作成したAssume Role自動化スクリプトの解説です。 このブログを読んだ誰かの参考になれば幸いです。