EC2にアタッチしたIAMロールからクロスアカウントでスイッチロールしてみる

普段はIAMユーザーからスイッチロールして使うことが多いIAMロール。今回はEC2にアタッチしたIAMロールからクロスアカウントでIAMロールへのスイッチしながら、スイッチロール元と先を制限しながら動作を確認してみます。
2020.10.31

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

こんにちは、コンサル部の鈴木(純)です。

IAMロールって基本的にはAWSサービスにアタッチするか、IAMユーザーからスイッチロールして使うことが多いですよね。今回はEC2にアタッチしたIAMロールからクロスアカウントでIAMロールへのスイッチをする機会があったので、試して行こうと思います。

やりたいこと

アカウントAのEC2にアタッチしたロール(SwitchFromRole)から、アカウントBに用意してあるロール(SwitchToRole)へスイッチして、アカウントBのアカウントにAWS APIを実行したい。

今回はロールを切り替えてS3にあるS3バケットの中身を確認してみます。

SwitchFromRole からは SwitchToRole のみにAssumeRoleできるよう、逆にSwitchToRole は SwitchFromRole からしかAssumeRoleできないように設定してみようと思います。

やってみる

今回アカウントが二つ登場するので、以下のようにアカウントIDを区別していきます。

  • アカウントA:111111111111
  • アカウントB:222222222222

アカウントAのロールを作成する

アカウントAでは適当なEC2インスタンスとEC2にアタッチするロール(SwitchFromRole)を作成します。EC2へのアクセスは今回SSM接続を使用するため、AWS管理ポリシーの「AmazonSSMManagedInstanceCore」を使用します。

今回は AssumeRole する先のロールも固定するため、先にそちらのポリシーを作成します。

JSONタブを開いて、以下のJSONを貼り付けます。xxxx…となっている部分はアカウントBのアカウントIDを入力しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAssumeCrossAccountRole",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::222222222222/SwitchToRole"
        }
    ]
}

Resource にはこれからスイッチする予定のarnを入れています。

ポリシーの確認に進み、適当な名前をつけて作成します。今回は switch-from-policy とつけてます。

まずはEC2にアタッチするロールを作成します。

次はEC2にアタッチするロールを作成していきます。

ロール作成画面を開いたら、EC2を選択して次へ進みます。

今回は先ほど作成したポリシーに加えて、「AmazonSSMManagedInstanceCore」のポリシーも追加でロールを作成しましょう。

最後にロール名を「SwitchFromRole」と入力し、ポリシーに先ほど選択した2つのポリシーが追加されていることを確認できれば、作成しましょう。

ここで作成したロールをEC2ロールにアタッチすればアカウントA側は準備完了です。

アカウントBのロールを作成する

次はアカウントBのロールを作成していきましょう。アカウントBに切り替えて作業をしていきます。

先にポリシーを作成しておきましょう。

作成手順については同じなので、JSONだけ載せておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAssumeCrossAccountRole",
            "Effect": "Allow",
            "Action": "sts:AssumeRole"
            "Resource": "*"
        }
    ]
}

ロール作成画面から「別のAWSアカウント」をクリックして、アカウントIDを入力します。ここではアカウントAのアカウントIDを入力して下さい。

同じようにポリシーをアタッチしていきます。今回はS3へのアクセスも付与するのでとりあえず「AmazonS3FullAccess」で実施しました。

これで準備完了といきたいところですが、今回はスイッチしてくるロールを絞りたいので、もう一つ作業が必要です。

SwitchToRole を開いて、「信頼関係」のタブを開いて信頼関係の編集をクリックします。

現在のポリシーが表示されるので、中身を以下のもので書き換えます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111/SwitchFromRole"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

ポリシーを保存すると、以下のように信頼されたエンティティがロールのARNに切り替わっていることを確認してください。

ここで作成したARNをメモっておきましょう。

ロールを切り替えてみる

ようやく準備が整ったので、早速ロールを切り替えてみます。アカウントAに戻り、SSMで起動したEC2へログインしましょう。

現在のロールを確認してみると以下のように表示されました。

$ aws sts get-caller-identity
{
    "Account": "111111111111",
    "UserId": "AROA5J5QSVFRXOTWUWE4F:i-03f267b92175ed7bf",
    "Arn": "arn:aws:sts::111111111111:assumed-role/SwitchFromRole/i-03f267b92175ed7bf"
}

デフォルトではEC2にアタッチした SwitchFromRole のロールが使用されていますね。

これをクロスアカウントで別のロールに切り替えるときの方法は以下のドキュメントの通り実施します。

IAM ロールの切り替え (AWS CLI)

EC2 インスタンスプロファイルのロールをクロスアカウントのロール (AWS CLI) に切り替えることができるようにするには デフォルトの CLI プロファイルを設定する必要はありません。代わりに、EC2 インスタンスプロファイルのメタデータから認証情報を読み込むことができます。ロールの新しいプロファイルを .aws/config ファイルに作成します。

.aws/configファイルに新しくプロファイルを作成してrole_arnをスイッチしたいロール名に書き換えれば良さそうですね。

vi ~/.aws/config を実行して以下を追記します。

[profile instancecrossaccount]
role_arn = arn:aws:iam::222222222222:role/SwitchToRole
credential_source = Ec2InstanceMetadata

プロファイルを使ってロールが切り替えられているか確認してみます。

$ aws sts get-caller-identity --profile instancecrossaccount
{
    "Account": "222222222222",
    "UserId": "AROAUNGTFQDFEPYNLRMOU:botocore-session-1604127150",
    "Arn": "arn:aws:sts::222222222222:assumed-role/SwitchToRole/botocore-session-1604127150"
}

ArnからSwitchToRole のロール名が確認できますね。

今回お試し用にアカウントBに作成したS3バケットを確認してみます。

$ aws s3 ls test-bucket-20201030 --profile instancecrossaccount
2020-10-30 01:37:41          4 test.txt

こちらも問題なくバケットの中身を確認することができました。

ロールの切り替えを制限できているかを確認

せっかくIAMロールの切り替えを制限したので、そちらが問題ないかも確認してみます。

まず、EC2にアタッチされているSwitchFromRole からは SwitchToRole にしかスイッチできないことを確認してみます。

アカウントBにSwitchToRole2というロールを用意して、同じように切り替えが可能か確認してみると以下のようにアクセス拒否されるのが確認できました。

$ aws sts get-caller-identity --profile instancecrossaccount2

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::111111111111:assumed-role/SwitchFromRole/i-03f267b92175ed7bf is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::222222222222:role/SwitchToRole2

逆にアカウントAのEC2ロールをSwitchFromRoleから変更した場合についても確認してみます。

この場合はSwitchToRoleの信頼関係でSwitchFromRoleのみを指定しているので、エラーとなるはずです。

EC2にアタッチするロールを変更して実行してみます。

$ aws sts get-caller-identity --profile instancecrossaccount

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::111111111111:assumed-role/SwitchFromRole2/i-03f267b92175ed7bf is not authorized to perform: sts:AssumeRole on resource:arn:aws:iam::222222222222:role/SwitchToRole

こちらも想定通りエラーとなりました。しっかりとスイッチする元のロールについても制限することができていることが確認できました。

まとめ

EC2ロールからのクロスアカウントのスイッチロールについて試してみました。

信頼関係部分などIAMは理解しづらい部分が多いので1つずつ理解していきたいですね。

参考情報

AWS JSON ポリシーの要素: Principal

IAM ロールの切り替え (AWS CLI)