【AWS】あるIAMロールに別のロールを引き受けられる（AssumeRole）ように設定する

タイトルのように設定を行う際に、2つの点でいつも混乱するので備忘録的にまとめる。
- 同一AWSアカウントのロールと、違うアカウント（クロスアカウント）のロールとで必要な設定内容が異なる
- 名前も役割もよく似たPassRoleと設定内容が異なる

# AssumeRoleとは

STS（Security Token Service）の提供するAPIアクションの一つ。
通常利用するユーザロールやサービスロールではアクセスできないAWSリソースへアクセスできるよう、別のロールの権限でアクションを実行するための一時的なセキュリティ認証情報（アクセスキーID、シークレットアクセスキー、およびセキュリティトークン）を生成する。

これで、あるロールが別のロールを「引き受け（assume）」、権限を得ることができる。
この機能を活用し、IAMロールごとに単体で持つAWSリソースへのアクセス権限を分散させ、あるロールに過剰な権限を集中させるような意図しない事態を回避でき、セキュリティ上の問題を軽減することにつなげられる。

# AssumeRoleの設定
あるIAMロールが別のロールを引き受けるには、まずは**引き受けられる**ロールの「**信頼関係（trust relationship）**」を編集する必要がある。
**引き受ける側ではないことに注意。**

そして、2つのロールが存在するAWSアカウントが同じかどうかで設定内容が違ってくる。
## 2つのロールが同一AWSアカウントにある場合
仮に`RoleA`と`RoleB`の2つのロールがあり、`RoleA`が`RoleB`を引き受けることを許可したいとする。AssumeRoleを実行すれば、`RoleA`が`RoleB`の権限を一時的に得られる。
このとき、下記のように**RoleBの信頼関係**を設定する。
便宜上、アカウントIDは000000000000とダミーのものにしている。
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::000000000000:role/RoleA"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
`RoleB`がサービスロール（ここではSystems Manager用のサービスロールとする）であるときには、下記のようになるだろう。
`Principal`の箇所の`Service`フィールドにSystems Manager（ssm）が指定されているところへ、`AWS`フィールドと`RoleA`のARNを追加する。
これで、`RoleB`は`RoleA`以外のIAMロールとSystems Manager以外のAWSサービスには引き受けられないように設定される。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::000000000000:role/RoleA",
                "Service": "ssm.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

## 2つのロールが違うAWSアカウントにある場合
上の場合と同様に`RoleA`と`RoleB`の2つのロールがあり、今回はこれらがそれぞれアカウントA（ID: 111111111111）、アカウントB（ID: 222222222222）で作成されているとする。
`RoleA`が`RoleB`を引き受けられるようにしたい。

`RoleB`の信頼関係は上と同様に設定する。
```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:role/RoleA"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

そして、**RoleAに対し**、下記の**許可ポリシー**（カスタマーインライン）を作成しアタッチする。ポリシー名は`AssumeRoleForRoleB`としている。
```:AssumeRoleForRoleB
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::222222222222:role/RoleB"
  }
}
```
この2点を設定することで、クロスアカウントでAssumeRoleが実現できる。
引き受ける側のロールについても**許可ポリシー**の設定を行う必要があるのが、上の場合との違いである。

# PassRoleとの違い
PassRoleは、ユーザやロールがそのロール（とアクセス許可）を別のロールに引き渡し、その別のロールが代わりにAWSリソースに対しアクションを実行できるようにすること。
STSではなく、IAM（Identity and Access Management）のアクション。
ロールの信頼関係ではなく、**許可ポリシーで指定できる。**

AssumeRoleとは対称的な機能で、管轄のサービスも設定箇所も異なる。

# 参考資料
- [AssumeRole - AWS Security Token Service](https://docs.aws.amazon.com/ja_jp/STS/latest/APIReference/API_AssumeRole.html)
- [AWS IAM: Allowing a Role to Assume Another Role](https://nelsonfigueroa.dev/aws-iam-allowing-a-role-to-assume-another-role/)
- [AWS のサービスにロールを渡すアクセス権限をユーザーに付与する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_passrole.html)
- [【AWS】iam:PassRoleとsts:AssumeRoleの違い](https://udomomo.hatenablog.com/entry/2020/09/20/222032)

AssumeRoleとPassRoleについてイメージで理解を深めたい方にはこの記事がおすすめ。
- [IAM ロールの PassRole と AssumeRole をもう二度と忘れないために絵を描いてみた](https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/)