ちょっと話題の記事

AWS CLIがAssumeRoleによる自動クレデンシャル取得とMFAに対応しました!

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

よく訓練されたアップル信者、都元です。本日リリースされたaws-cli 1.6.0では、大きく2つの機能が追加になっています。一つはWaiters、こちらはAWS CLIのWaitersによる待ち受け処理を実装するを御覧ください。本エントリーでは、AssumeRoleとMFAについて。

AWS CLIにおける永続キーの管理

AWS CLIで数多くのAWSアカウント(APIアクセスCredentials)を扱う場合、~/.aws/credentialsファイルに、複数のプロファイルを作成し、それぞれにアクセスキー・シークレットアクセスキーを記述します。#以降はコメントとして扱われるので、私は下記のように、AWSアカウントIDも記述しておいたりしています。

~/.aws/credentials

[foo]
# 111122223333
aws_access_key_id = AKIAXXXXXXXXXXXXXXXX
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

[bar]
# 222233334444
aws_access_key_id = AKIAYYYYYYYYYYYYYYYY
aws_secret_access_key = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

AWS CLIにおける一時キーの管理【従来編】

しかし、管理上の理由からIAMユーザを発行されず、IAM Roleを介した一時キーでの操作が必要になることもあります。具体的にはこんな感じ。

2014-11-11_1559

オペレータとしてIAMユーザを発行され、そのユーザに紐づくAPI Credentials(永続キー)は持っているとします。このAWSアカウントをここでは、前述のfooにしましょう。

そして、実際に操作したいAWSアカウントがtarget1target2です。しかし、オペレータはこれらのアカウントのAPI Credentialsはおろか、IAMユーザも持っていない状況を考えます。

この場合、それぞれのtargetアカウント上にIAM Roleを作成し、下記の手順を踏むことで、targetに対するAPIアクセスが可能です。

  1. まず、fooのcredentialsは従来どおり記述する。

    ~/.aws/credentials

    [foo]
    # 111122223333
    aws_access_key_id = AKIAXXXXXXXXXXXXXXXX
    aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  2. gatewayのIAM Userに発行された永続キー(long-term security credentials)を使って、target上のIAM Roleに対するAssumeRoleリクエストを行う。
    $ aws --profile foo sts assume-role \
        --role-arn arn:aws:iam::333344445555:role/target1-role \
        --role-session-name test
  3. その結果、返されるcredentials(アクセスキー・シークレットキー・トークンの組)を、下記のように~/.aws/credentialsに記入する。

    ~/.aws/credentials

    [target1]
    # 333344445555
    aws_access_key_id = AKIAZZZZZZZZZZZZZZZZ
    aws_secret_access_key = zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
    aws_session_token = ....
  4. このプロファイルを利用してAWS CLIを呼び出す。
    $ aws --profile target1 ...

ただし、一時キーは長くても36時間で期限が切れてしまうため、credentialsファイルに静的に書き込むにはあまり向いていませんでした。

AWS CLIにおける一時キーの管理【自動クレデンシャル取得】

本日リリースされたAWS CLIでは、上記のような作業を一発で行うため、~/.aws/config内に、このような記述ができるようになりました!

~/.aws/config

[profile target1]
# 333344445555
role_arn = arn:aws:iam::333344445555:role/target1-role
source_profile = foo

この設定さえ書いておけば、一時キーの期限切れを意識せずに、いつでも aws --profile target1 ... という形でコマンドを呼び出すことができます。便利ですねー!

~/aws/credentialsファイルは、AWS CLIだけではなく、各言語のAWS SDKsからも参照される「共有credentialsファイル」です。しかし、上記のrole_arn及びsource_profileによるAPIアクセス機能は、あくまでもAWS CLI固有の機能です。各言語のAWS SDKsはrole_arn及びsource_profileという記述を理解できないため、この記述は共有credentialsファイルではなく、AWS CLI固有の設定ファイルである~/.aws/configに記述する必要があります。

AWS CLIにおける一時キーの管理【MFA編】

さらに、今回のアップデートでは、従来できなかったことが、もう一つできるようになっています。CLIにおけるMFA認証です。前述の図中で、さらっとtrustと書いた部分ですが、このポリシーにおいて「信頼はするけど、MFA認証が成功した場合に限る」という設定が可能です。具体的にはこんなポリシー。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Null": {
          "aws:MultiFactorAuthAge": false
        }
      }
    }
  ]
}

このようなtrustポリシーであった場合、MFAのコードを与えない限り、AssumeRoleリクエストが失敗します。MFAの入力方法は、下記のような感じです。IAMユーザfooには、あらかじめMFAを設定しておきます。

$ aws --profile foo sts assume-role \
    --role-arn arn:aws:iam::444455556666:role/target2-role \
    --role-session-name test \
    --serial-number arn:aws:iam::111122223333:mfa/foo \
    --token-code 998877

新しいAWS CLIでは、上記のようなMFA認証にも対応しています。

~/.aws/config

[profile target1]
# 444455556666
role_arn = arn:aws:iam::444455556666:role/target2-role
mfa_serial = arn:aws:iam::111122223333:mfa/foo
source_profile = foo

~/.aws/config内に上記のような設定をしておくと、コマンド実行時に毎回MFAのコード(6桁)を問われます。

$ aws --profile target2 ...
Enter MFA code: 998877 ←本来はechoされません
{
  ...結果...
}

RoleとMFAを使って、よりセキュアに複数アカウントのAPI Credentialsを扱えるようになったと想います。積極利用していきたいですね。