coinbase/assume-role でシュッと多要素認証を突破して、マルチアカウント環境で快適にTerraformライフを送る

なにこれ?

CLIコンソールで、AWSのIAMユーザの多要素認証(MFA)を簡単に実行できる。

背景

Terraform 単体だと、多要素認証したうえで AssumeRole することができない。terraform-provider-aws リポジトリIssue も立てられているが、しばらく対応予定はないらしい。

At this time we do not have plans to support interactive authentication to providers since it would require some significant changes to the provider model.

とはいえ、AWS Organizationsなどを使って、マルチアカウント管理する環境だと、これでは困る。そんなわけで、coinbase/assume-roleの出番である。

セットアップ

profile 設定

AWS CLI の profile 設定に AssumeRole 元のアカウントの設定を書く。 後述する AWS_PROFILE_ASSUME_ROLE には、この情報が使われる。

$ vi ~/.aws/credentials
[custodian]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

$ vi ~/.aws/config
[profile custodian]
output = json
region = ap-northeast-1

インストール

$ brew tap coinbase/assume-role
$ brew install assume-role

rcファイルの設定

assume-role コマンドを、どこからでも使えるようにする。AWS_PROFILE_ASSUME_ROLE には、事前準備で定義した profile 名と一致させること。

$ echo 'source $(which assume-role)' >> ~/.bashrc
$ echo 'export AWS_PROFILE_ASSUME_ROLE=custodian' >> ~/.bashrc
$ source ~/.bashrc

AssumeRole先のIAMロールの設定

AWSマネジメントコンソールなどから、AssumeRole 先アカウント 123456789012 に、事前に admin というIAMロールを定義する。

IAMロール

AssumeRole 元アカウント(999999999999)から、AssumeRoleできるように、AssumeRolePolicyDocumentを定義しておく。また、AssumeRole時に多要素認証を強制できるように aws:MultiFactorAuthPresent を有効にしているものポイントである。

$ aws iam get-role --role-name admin
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Condition": {
                        "Bool": {
                            "aws:MultiFactorAuthPresent": "true"
                        }
                    },
                    "Principal": {
                        "AWS": "arn:aws:iam::999999999999:root"
                    }
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleId": "AROAJAGBE3JR3XXXXXXXX",
        "CreateDate": "2018-08-04T02:53:23Z",
        "RoleName": "admin",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:role/admin"
    }
}

IAMポリシー

とりあえず雑に、AdministratorAccessをアタッチする。実際にはこんな適当なポリシーをアタッチしてはいけない。

$ aws iam list-attached-role-policies --role-name admin
{
    "AttachedPolicies": [
        {
            "PolicyName": "AdministratorAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
        }
    ]
}

使い方

準備が終わったので、さっそく AssumeRole してみる。

AssumeRole

アカウント 123456789012 に先ほど定義した admin というロールに AssumeRole する。

$ assume-role 123456789012 admin

これを叩くと、MFA Tokenの入力を促されるので、入力する。

確認

AssumeRole できてることを確認。

$ aws sts get-caller-identity
{
    "Account": "123456789012",
    "UserId": "AROAJAGBE3JR3XXXXXXXX:1530693780",
    "Arn": "arn:aws:sts::123456789012:assumed-role/admin/1530693780"
}

このあとは、Terraform だろうがなんだろうが、好きなツールを AssumeRole した状態で使うことができる。

宣伝

AWS Organizationsに関する記事を以前書いたので、よかったらこちらもどうぞ。