AWS の各種ポリシーの整理：シンプルに理解するコツ

AWS には IAM ポリシー、リソースポリシー、信頼ポリシー（AssumeRole）など複数の種類のポリシーが存在し、初学者にとってはその違いを理解するのが難しいポイントの一つです。
とはいえポリシーは AWS で一番魅力的だと思っている概念ですので、個人的に頭を整理した内容を記載します。

## AWS ポリシーの基本構造

主なポリシーのステートメントの構成要素として下記があります。

- Effect
- Action
- Resource

もちろん、[他にもあります](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements.html)が、シンプルに理解するため一旦忘れます。
こうすると、Effect = Allow の場合は、

「Action に記載した操作を Resource に記載したリソースに対して許可する」

と理解できます。

※ 以降、分かりやすさを重視するため、Effect は Allow である前提で記載していきます

この許可を誰に与えるのか ? で、ポリシーの種類が変わります。
表にするとこんな形で許可することになります。

| 誰が?                    | 何の操作を?     | 何に対して?             |
| ------------------------ | --------------- | ----------------------- |
| (ポリシーによって変わる) | Action の操作を | Resource の対象に対して |

## 各ポリシーの理解

### IAM ポリシー：ロールやユーザーが何をして良いかを定義する

IAM ポリシーは、特定の IAM エンティティ（ユーザー、グループ、ロール）に対して付与される権限を定義します。
これを IAM ロールや IAM ユーザーと関連付けることで、対象に対する許可を与えることができます。

下記は、開発者が S3 バケットと DynamoDB テーブルにアクセスするための IAM ポリシーの例です：

```json:IAM ポリシーの例
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-app-bucket",
                "arn:aws:s3:::my-app-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:Query"
            ],
            "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/Users"
        }
    ]
}
```

表に整理すると下記のような形でしょうか ?

| 誰が?                                      | 何の操作を?     | 何に対して?             |
| ------------------------------------------ | --------------- | ----------------------- |
| IAM ポリシーを割り当てたロール、ユーザーが | Action の操作を | Resource の対象に対して |

### リソースポリシー：リソース自身が何を受け入れるかを定義する

リソースポリシーの場合は、ポリシー自体が関連付いているリソースに対する許可ではなく、
「リソースに対して誰がアクセスして良いか」を下記に記載します。

- Principal

KMS のキーポリシーや、S3 のバケットポリシーが該当します。

下記は S3 バケットの特定の IAM ロールからのアクセスを許可する例です：

```json:リソースポリシーの例
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAppAccess",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/MyAppRole"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::my-app-bucket/*"
        }
    ]
}
```

表に整理すると下記のような形でしょうか ?

| 誰が?                          | 何の操作を?     | 何に対して?             |
| ------------------------------ | --------------- | ----------------------- |
| Principal のロール、ユーザーが | Action の操作を | Resource の対象に対して |

### 信頼ポリシー（Trust Policy/AssumeRole）：ロールを引き受けることができる対象を定義する

こちらは IAM ロールの中に記載するポリシーで、一時的にロールの権限を与える対象を定義します。
例えば Lambda から他のリソースへのアクセスが必要な場合、Lambda の実行用のロールを定義しますがこれは常に Lambda のリソースが持っている権限というわけではありません。
Lambda が動作する際に一時的にロールの権限を得る動きになります。
このため、一時的に誰に許可を与えて良いかの定義を下記に記載します。

- Principal

Lambda の場合は `"Service": "lambda.amazonaws.com"` が記載されている必要があります。

```json:Lambda の信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

表に整理すると、一時的な権限であることは置いておくとリソースポリシーと同様になりますね。

| 誰が?                    | 何の操作を?     | 何に対して?             |
| ------------------------ | --------------- | ----------------------- |
| Principal のリソース等が | Action の操作を | Resource の対象に対して |

## まとめ

AWS のポリシーは AWS リソース間の通信や操作に関する許可を定義するもので、クラウドを適切に構成する際に非常に重要な要素になります。
実際に使用する際はもう少し詳細に理解が必要n場合もありますが、ポリシーを理解する第一歩としては「Action の操作を Resource に許可する」を軸に考えると良いと思いました。