AWS CLI を MFA を都度入力せずにスイッチロールと共に12時間連続で利用する方法

記事タイトルとURLをコピーする

マネージドサービス部 佐竹です。
本日は MFA が必須となっている AWS アカウントに対して、ローカル PC から AWS CLI を用いてスイッチロールを行うときのお話です。

はじめに

前提として、AWS CLI の実行においては、全て AWS CloudShell で運用したい。私はそう考えていたりします。しかし、AWS CLI をローカル PC から実行しないといけないシーンもまだまだ存在するのが実情です。

そしてAWS CLI を MFA 必須の AWS アカウントで実行すると、都度 MFA のコードを聞かれてしまう場合って、ありますよね。非常に手間で面倒なものです。そして、1時間で期限が切れてしまう、ということもあります。

今回は AWS CLI で MFA を都度入力せずに12時間連続で利用する方法について記載します。

この内容に関するブログは世の中に色々あると思うのですが、今回は比較的 AWS CLI 初心な方向けになるべく詳細な検証結果を添えてお伝えします。

前提

既に AWS CLI が実行できる環境をお持ちの方対象にしています。インストールと設定がまだの方は、以下の公式ドキュメントを参考に実施ください。

docs.aws.amazon.com

docs.aws.amazon.com

AWS CLI で IAM Role を切り替える

1-1. IAM ステップアカウントで sts get-session-token

IAM ステップアカウントで get-session-token をするところから試してみましょう。get-session-token に関する仕様は以下をご確認ください。

docs.aws.amazon.com

今から行うオペレーション (1-1) を図にすると、以下の通りです。

「Account Left 123456789012」は、 IAM ステップアカウント(踏み台アカウント)として動作するアカウントです。この「Account Left 123456789012」に対して、AWS CLI を実行します。

AWS CLI の実行前提として、「Account Left 123456789012」には IAM User satake@serverworks.co.jp が払い出し済であり、またこの IAM User には AKIA5FQU5HPBMDQ3CEH7 というアクセスキーを作成済とします。加えて、本 AWS アカウントでは全ての IAM ユーザで MFA が必須となっている状況とします。

この状況において、ローカル PC に設定する「Config」ファイルと、「Credentials」ファイルの記述内容は以下の通りとします。*1

Config

[profile iam_step_user]
region = ap-northeast-1

Credentials

[iam_step_user]
aws_access_key_id = AKIA5FQU5HPBMDQ3CEH7
aws_secret_access_key = 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

AWS CLI の実行

早速、AWS CLI を実行していきましょう。コマンドは以下の通りです。この時、MFA のシリアルナンバーとなる Arn と、MFA の6桁の数字を同時に入力します。*2

aws sts get-session-token --profile iam_step_user --serial-number arn:aws:iam::123456789012:mfa/satake@serverworks.co.jp --token-code 815685

参考までに、引数ごとに改行したバージョンも以下に記載します。

aws sts get-session-token
--profile iam_step_user
--serial-number arn:aws:iam::123456789012:mfa/satake@serverworks.co.jp
--token-code 815685
MFA の Arn の調べ方

なお、自身の MFA の Arn が不明な場合は、マネジメントコンソールにログイン後、画面右上から「Security credentials」を押下し「My security credentials」を表示させてください。

画面中央あたりに「Multi-factor authentication (MFA)」の項目がありますので「Identifier」の値を取得してください。

AWS CLI の実行結果

権限が正しい場合、上記のコマンドを実行すると以下のような返り値が得られるはずです。

{
    "Credentials": {
        "AccessKeyId": "ASIA5FQU5HPBP27YWKHE",
        "SecretAccessKey": "+i7ZZ5gGRCwM+9hn25cliZWJ+R9UBQXsREA9coA9",
        "SessionToken": "IQoJb3JpZ2luX2VjEFYaDmFwLW5vcnRoZWFzdC0xIkcwRQIhAJyWFkfm79G+dVgXOudIhKgDpY0cqqOg8YIBXSN3/tdAAiAewstugDog1+pldsmqP2SNXVaZt98dFWgjE2wN7Cp/tCr4AQjP//////////8BEAAaDDkwNTIwODIxNjUxNCIM+dP1dY1yivKc60RwKswB0TqbYdFgShBwwPuM6HlM0pt5eDZMUZ2oUCqU7iKsKTxgdkBbcy+YT+bXOi25DFO2HUPVWTrrtuU/iJyy95ViZPQXtVIO4ssj5NmdHeDhbiEwdGv3oocL+oEa8SCpcsgyXghx49VexgbGAOnn+RPCbAaI78CQ9U/04F06sPNw8ACeVENhbpwrdJtLGLwGSLZNmJlROMC1/fZmLq1rEcr25b2p+QG6J2HMFFblWdy9D9o+GOnLcX9E9NXbjmVe3ZPdjdjxi+MB94hYZqlBMOeKuaUGOpgBMNBVHIlyaEcTorI3XFqpeTxzICArERf7xi6IcAQfoNzPjE/W7rS/Qay4n5oMC0RlfIV4TftMIAfuhjdS1tXjeq/Lx7Awf8S/8GGhDmPHPz/oj3m2xl4ts+XFZ/8EsHmIpyB+zgQr5kkbug7WcFTbqMCrUE8jmZXhO+RZmHWgPK7l4Rhmesi82QBorL+gdo7GF5x8mTiVm1d=",
        "Expiration": "2023-07-13T18:17:11+00:00"
    }
}

これが「一時的な認証情報」と呼ばれるもので、有効期限のあるアクセスキーです。

有効期限について (duration-seconds)

上記の返り値には "Expiration": "2023-07-13T18:17:11+00:00" という有効期限が UTC で記載されています。

この有効期限については、先の AWS 公式ドキュメントに以下の通り記載があります。

The GetSessionToken operation must be called by using the long-term Amazon Web Services security credentials of an IAM user. Credentials that are created by IAM users are valid for the duration that you specify. This duration can range from 900 seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours), with a default of 43,200 seconds (12 hours). Credentials based on account credentials can range from 900 seconds (15 minutes) up to 3,600 seconds (1 hour), with a default of 1 hour.

(以下和訳)

GetSessionTokenオペレーションは、IAM ユーザーの長期アマゾン ウェブ サービス セキュリティ認証情報を使用して呼び出す必要があります。 IAM ユーザーによって作成された認証情報は、指定した期間まで有効となります。 この期間は CLI 実行時に 900 秒 (15 分) から最大 129,600 秒 (36 時間) までの範囲で指定でき、デフォルトは 43,200 秒 (12 時間) です。 アカウント資格情報に基づく資格情報の範囲は 900 秒 (15 分) から最大 3,600 秒 (1 時間) で、デフォルトは 1 時間です。

引数で明示的に指定しない場合 Duration は「デフォルトは 43,200 秒 (12 時間) です」ため、もしこれを変更したい場合は、引数で明示的に指定する必要があります。

aws sts get-session-token --profile iam_step_user --duration-seconds 129600 --serial-number arn:aws:iam::123456789012:mfa/satake@serverworks.co.jp --token-code 815686

上記は --duration-seconds を指定する場合の例です。

1-2. 手に入れた認証情報を使ってさらに sts assume-role する

先ほど手に入れた一時的な認証情報を「Config」ファイルと、「Credentials」ファイルに追記して利用してみます。

実際に各ファイルに記載する情報は以下の通りです。

Config

[profile sessiontoken]
region = ap-northeast-1

Credentials

[sessiontoken]
aws_access_key_id = ASIA5FQU5HPBP27YWKHE
aws_secret_access_key = +i7ZZ5gGRCwM+9hn25cliZWJ+R9UBQXsREA9coA9
AWS_SESSION_TOKEN = IQoJb3JpZ2luX2VjEFYaDmFwLW5vcnRoZWFzdC0xIkcwRQIhAJyWFkfm79G+dVgXOudIhKgDpY0cqqOg8YIBXSN3/tdAAiAewstugDog1+pldsmqP2SNXVaZt98dFWgjE2wN7Cp/tCr4AQjP//////////8BEAAaDDkwNTIwODIxNjUxNCIM+dP1dY1yivKc60RwKswB0TqbYdFgShBwwPuM6HlM0pt5eDZMUZ2oUCqU7iKsKTxgdkBbcy+YT+bXOi25DFO2HUPVWTrrtuU/iJyy95ViZPQXtVIO4ssj5NmdHeDhbiEwdGv3oocL+oEa8SCpcsgyXghx49VexgbGAOnn+RPCbAaI78CQ9U/04F06sPNw8ACeVENhbpwrdJtLGLwGSLZNmJlROMC1/fZmLq1rEcr25b2p+QG6J2HMFFblWdy9D9o+GOnLcX9E9NXbjmVe3ZPdjdjxi+MB94hYZqlBMOeKuaUGOpgBMNBVHIlyaEcTorI3XFqpeTxzICArERf7xi6IcAQfoNzPjE/W7rS/Qay4n5oMC0RlfIV4TftMIAfuhjdS1tXjeq/Lx7Awf8S/8GGhDmPHPz/oj3m2xl4ts+XFZ/8EsHmIpyB+zgQr5kkbug7WcFTbqMCrUE8jmZXhO+RZmHWgPK7l4Rhmesi82QBorL+gdo7GF5x8mTiVm1d=

この一時的な認証情報を利用すれば MFA を都度入力することなしに、AWS CLI が実行可能です。

aws iam list-users --profile sessiontoken

例ですが、上記のコマンドも実行が可能です。

さて、この情報を利用して、他のアカウントの一時的な認証情報を得てみましょう。

図にすると、上図のイメージです。*3

得られた一時的な認証情報を用いて「Account Right 123456789034」に対しても AWS CLI を実行してみようという状態です。

これには assume-role コマンドを用います。

docs.aws.amazon.com

実際のコマンドは以下の通りです。

aws sts assume-role --role-arn "arn:aws:iam::123456789034:role/ServerworksRolePU" --role-session-name AWSCLI-satake@serverworks.co.jp --profile sessiontoken

参考までに、引数ごとに改行したバージョンも以下に記載します。

aws sts assume-role
--role-arn "arn:aws:iam::123456789034:role/ServerworksRolePU"
--role-session-name AWSCLI-satake@serverworks.co.jp \・・・必須項目。任意のセッション名を記載
--profile sessiontoken
AWS CLI の実行結果

上記のコマンドを実行すると以下の返り値が得られました。

{
    "Credentials": {
        "AccessKeyId": "ASIAZYZSYNI5QCYXF266",
        "SecretAccessKey": "02Ri+BFGdwk67lfk3qAUY7UmnVG9AM97nr5RVcpf",
        "SessionToken": "IQoJb3JpZ2luX2VjEFYaDmFwLW5vcnRoZWFzdC0xIkcwRQIhAPycWJhmynFQZXJnBZQeBHPZdq1H2CTN0aVDvy4bh+5BAiAGmILWAu72Wz9a7lSK7SqT3QHZXKhnzmcRp7EseACAfiq5AgjQ//////////8BEAEaDDY3MTczMTk2ODU3MSIMgnjuvSLvkaBIPKX3Ko0C7IdgGI49BEvICsoQHpsnbGgV33JL4hGnaSS9wDDfMCza+fYdhRJGvTfPG5YOWjJMFsTfr6PaFcfIX+vLJHKfzcTYF9lUlG7+VxYSyJYBgNl5UrZbuJg5l0N0KL1wAKCCM1roEt02GiqdYIhfBVCUpL54O/HVPqpkXWpNn5w1TgS5vvBKrfbHIwOpsttT1y308OXKbtMMCuyPGJGpazAyima9arGsy0GF/4uSRFuhRNfYF3vi/i08YkdrDYerVxp4wFIFM2wJUYSWjbvWqIMQyVv/WEkZfFT0VZ1ZdGn0i054q4s/GMITK9bnPhFO7uVkf0rZmhlJjfOsBueQx+Bss2psqxN16hmgRCwS4iUw7JO5pQY6nQHNKusog8Bo5tjd3f8zdYG1zvGF/cQ2q24zgf2tWH57Xrwtz0GCnOF8ZSfwlGhow15OW0cbPTZLKz15PYral8sTkmDt4SF+IyboKRqxWmQQrMPsHZfvQfHHBn+mDbP0H/K3c+/TQqpewWD9npcXbSF50LVhA1g62MZ/GmshQm5JuRg+iEXlxMb6r/qevZVPd0iXJarjHYH6uFHiwbsz",
        "Expiration": "2023-07-12T07:36:28+00:00"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAZYZSYNI53UAG45JR3:AWSCLI-satake@serverworks.co.jp",
        "Arn": "arn:aws:sts::123456789034:assumed-role/ServerworksRolePU/AWSCLI-satake@serverworks.co.jp"
    }
}

これは、「Account Right 123456789034」にログインが可能となる一時的な認証情報です。先ほどと同様にこの一時的な認証情報を「Config」ファイルと、「Credentials」ファイルに追記して利用することが可能です。

有効期限について (duration-seconds)2

上記の返り値には "Expiration": "2023-07-12T07:36:28+00:00" という有効期限が UTC で記載されています。

AWS 公式ドキュメントの通りですが assume-role の場合は「By default, the value is set to 3600 seconds.」と記載があるように、この有効期限は1時間がデフォルトとなっています。

さて、ではこれを「3601」秒と、1秒でも増やしてみるとどうでしょう?

aws sts assume-role --role-arn "arn:aws:iam::123456789034:role/ServerworksRolePU" --role-session-name AWSCLI-satake@serverworks.co.jp --profile sessiontoken --duration-seconds 3601

結果は、以下のエラーです。

An error occurred (ValidationError) when calling the AssumeRole operation:
The requested DurationSeconds exceeds the 1 hour session limit for roles assumed by role chaining.

どういうことでしょうか?

この件について、先の AWS 公式ドキュメントにおいて以下の通り記載があります。

Role chaining limits your Amazon Web Services CLI or Amazon Web Services API role session to a maximum of one hour. When you use the AssumeRole API operation to assume a role, you can specify the duration of your role session with the DurationSeconds parameter. You can specify a parameter value of up to 43200 seconds (12 hours), depending on the maximum session duration setting for your role. However, if you assume a role using role chaining and provide a DurationSeconds parameter value greater than one hour, the operation fails.

(以下和訳)

ロールチェーンでは、アマゾン ウェブ サービス CLI またはアマゾン ウェブ サービス API のロール セッションが最大 1 時間に制限されます。 AssumeRole API オペレーションを使用してロールを引き受ける場合、DurationSeconds パラメーターを使用してロール セッションの期間を指定できます。 ロールの最大セッション期間の設定に応じて、最大 43200 秒 (12 時間) のパラメーター値を指定できます。 ただし、ロール チェーンを使用してロールを引き受け、1 時間より大きい DurationSeconds パラメーター値を指定すると、操作は失敗します。

まず上記の「ロールの最大セッション期間の設定」というのは、IAM Role における以下の設定を指します。

Maximum session duration

本設定はデフォルトで 3600 秒 (1時間) となっていますが編集により延長が可能です。現在の設定値は、編集により最大値が既に 43200 秒 (12 時間) と設定されている通りで、本検証の AssumeRole の CLI においても想定としては最大 43200 秒 (12 時間) まで指定が可能なはずです。

しかし、今回は「role chaining」に抵触するとして、3601秒の CLI は失敗しています。

この「role chaining」という言葉や概念が少々理解しにくいのですが「一時的な認証情報を使ってさらに一時的な認証情報を得る」ということと理解頂けばと存じます。この場合に「role chaining」として扱われるため、3600 が上限となってしまいます。

そのため、sts で get-session-token した一時的な認証情報を用いて他のアカウントに assume-role をすると「期限が1時間に限定されてしまう」ために、本ブログの題名にも記載した「目的」となる「12時間連続で利用する」が満たせません。

ここまでのまとめ

1-1, 1-2 の検証結果をまとめると上図のようになるでしょうか。

1段階目として get-session-token 、2段階目にその一時的な認証情報を用いた assume-role を色違いの一点鎖線で表しています。

一旦、get-session-token から始まる検証はここで終わります。

2. IAM ステップアカウントのアクセスキーで直接 sts assume-role

というわけで、こちらが本題です。

先ほどのやり方は、マネジメントコンソールアクセス時に、IAM ステップアカウントに一度入った後さらにその他の AWS アカウントにスイッチロールする方法に似ています。ただこのやり方では、一時的な認証情報の使用期限が最大1時間になってしまいます。

期限を最大値である12時間まで延ばすためには、直接「Account Right 123456789034」に assume-role を行う必要があります。

図にすると上図のようなイメージです。ようは、予め IAM ステップアカウントで get-session-token を行う必要はありません。

AWS CLI の実行

早速コマンドです。

aws sts assume-role --role-arn "arn:aws:iam::123456789034:role/ServerworksRolePU" --role-session-name AWSCLI-satake@serverworks.co.jp --profile iam_step_user --duration-seconds 43200 --serial-number arn:aws:iam::123456789012:mfa/satake@serverworks.co.jp --token-code 496031

説明のために、改行したバージョンも以下に記載します。実際はワンライナーで実行してください。

aws sts assume-role \
--role-arn "arn:aws:iam::123456789034:role/ServerworksRolePU" \・・・Account RightIAM Role を指定
--role-session-name AWSCLI-satake@serverworks.co.jp \・・・必須項目。任意のセッション名を記載
--profile iam_step_user \・・・Account Left で取得済の Credentials を利用(本文 1-1 で記載済の Profile を使用)
--serial-number arn:aws:iam::123456789012:mfa/satake@serverworks.co.jp \・・・Account Left (IAM ステップアカウント)に登録された MFAArn
--duration-seconds 43200 \・・・最大接続時間(秒)
--token-code 496031 \・・・MFA の数字6桁
AWS CLI の実行結果

上記コマンドが成功すると、以下の返り値が得られました。

{
    "Credentials": {
        "AccessKeyId": "ASIAZYZSYNI5Y2MD33NF",
        "SecretAccessKey": "qbqSsb5s2JSJ3w8AuOmeju2cPydFtUAWBPDjc0En",
        "SessionToken": "IQoJb3JpZ2luX2VjEFoaDmFwLW5vcnRoZWFzdC0xIkcwRQIhALtMJAw2Sx0MahIX6TXWaPiouCS6tYYTPJRpFT7ydRaSAiALArJ8l6cmS8VAhkYMGOZbWvI9rmSaV7p6or4Z2fQA4iq2AgjT//////////8BEAEaDDY3MTczMTk2ODU3MSIMJfzLc2xWXR8XacEwKooCR6/+onzCmm36BfA9f/z17h4a2zv1D44Yqaae1WcvNcJGiF3R4iH5dBGEgp+tjoG0OI3rixzqyTVxXB8S/73M3Sf6/wBFEYAweouyqTToeFVU0JR8POPAsq/wk4xMxH/XADJe2g8X0Km8CjrSRZDZ8UbnmyyHwUy/8In53X3wQ5xsLTOFdZLeA8QjbGheEPDxBYDPF9kRXBKJiW7D89lk8ZDaovLl2M3drU21tb37JfGu0GfclL6toy0uEKDW6WcPHvZPqLcT7qiM3j0dtgX0rp0nY3YK/qv+C6UzZQ6ARANLLeyFRWNY3xg6ixD6tnBVXnettamZGXJ/UWzhH/xc7YJH6kComifPJeIw1+25pQY6nQHkzWWIr/KzZNp/6jsUUj+r/KF8xQ82L8q4+RXYTOC1dot82YQj2CYEJ0jqaUnKyggxzhTWly4vz2LvU7/pO7gt2P1whVQOefFswrpKZReyJ/FOyW2EgUAL16XnbbQe9+LgtV7hnFU6TlQByACTNtdUhqtnRFqpQXfSfCBbeXqp7zMlfSzBvMjksPdqDBdVIuUsNAClei5kWSZMO/xo",
        "Expiration": "2023-07-12T21:48:07+00:00"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAZYZSYNI53UAG45JR3:AWSCLI-satake@serverworks.co.jp",
        "Arn": "arn:aws:sts::123456789034:assumed-role/ServerworksRolePU/AWSCLI-satake@serverworks.co.jp"
    }
}

先ほどと同様にこの一時的な認証情報を「Config」ファイルと、「Credentials」ファイルに追記して利用することが可能であり、この一時的な認証情報の有効期限は12時間となっています。

実際に記載する例をこちらにも掲載しておきます。

Config

[profile sessiontoken-12hr]
region = ap-northeast-1

Credentials

[sessiontoken-12hr]
aws_access_key_id = ASIAZYZSYNI5Y2MD33NF
aws_secret_access_key = qbqSsb5s2JSJ3w8AuOmeju2cPydFtUAWBPDjc0En
AWS_SESSION_TOKEN = IQoJb3JpZ2luX2VjEFoaDmFwLW5vcnRoZWFzdC0xIkcwRQIhALtMJAw2Sx0MahIX6TXWaPiouCS6tYYTPJRpFT7ydRaSAiALArJ8l6cmS8VAhkYMGOZbWvI9rmSaV7p6or4Z2fQA4iq2AgjT//////////8BEAEaDDY3MTczMTk2ODU3MSIMJfzLc2xWXR8XacEwKooCR6/+onzCmm36BfA9f/z17h4a2zv1D44Yqaae1WcvNcJGiF3R4iH5dBGEgp+tjoG0OI3rixzqyTVxXB8S/73M3Sf6/wBFEYAweouyqTToeFVU0JR8POPAsq/wk4xMxH/XADJe2g8X0Km8CjrSRZDZ8UbnmyyHwUy/8In53X3wQ5xsLTOFdZLeA8QjbGheEPDxBYDPF9kRXBKJiW7D89lk8ZDaovLl2M3drU21tb37JfGu0GfclL6toy0uEKDW6WcPHvZPqLcT7qiM3j0dtgX0rp0nY3YK/qv+C6UzZQ6ARANLLeyFRWNY3xg6ixD6tnBVXnettamZGXJ/UWzhH/xc7YJH6kComifPJeIw1+25pQY6nQHkzWWIr/KzZNp/6jsUUj+r/KF8xQ82L8q4+RXYTOC1dot82YQj2CYEJ0jqaUnKyggxzhTWly4vz2LvU7/pO7gt2P1whVQOefFswrpKZReyJ/FOyW2EgUAL16XnbbQe9+LgtV7hnFU6TlQByACTNtdUhqtnRFqpQXfSfCBbeXqp7zMlfSzBvMjksPdqDBdVIuUsNAClei5kWSZMO/xo

あとはこの profile を引数に用いて AWS CLI を実行してください。

こちらの方法であれば、MFA を都度入力せずに12時間連続で AWS CLI を実行することが可能となります。

まとめ

直接 sts assume-role する構成図の再掲

本ブログでは、AWS CLI を MFA を都度入力せずにスイッチロールと共に12時間連続で利用する方法として、実際のコマンドと設定について記載しました。

なるべく分かり易くなるように図を添えたのですが、うまく伝わったでしょうか。

get-session-token を先に行うことなく、assume-role を直接的に行うほうが良い理由が、仕様と共にご理解いただければ嬉しく思います。

また本ブログが AWS CLI がより使いやすくなるためのヒントになれば幸いです。

では、またお会いしましょう。

*1:これ以降の本ブログに表示されている AWS Secret Access Key はダミー値です

*2: 「sts get-session-token」 は MFA なしでも実行できるようになっている場合でも、MFA を引数に入力してください。MFA を通した一時クレデンシャルを取得しない限り "aws:MultiFactorAuthPresent": "false" のままとなり、"true" フラグが立ちません

*3:通常の Credentials(アクセスキー)のアイコンには時計のマークがありませんが、一時的な認証情報のアイコンには時計マークが右下に設置されている点にも注目ください。

佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ

マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023 Japan AWS Top Engineers/2020-2023 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。