AWS CLI上からAssume Roleするスクリプトを作成してめんどくさい作業を自動化してみた

2024.05.17

リテールアプリ共創部のるおんです。 特定のプロジェクトの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をクラスメソッドの先輩方の記事を参考に作成してみました!
参考:

先輩方に感謝しながらAssume Roleスクリプト書いてみました

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自動化スクリプトの解説です。 このブログを読んだ誰かの参考になれば幸いです。

参考