IAMロールとポリシーを使いこなすためのポイント(1/2)

この記事は、ソリューションアーキテクトの勉強を始めた方やIAMについての理解を深めたい方向けに作成しています。

初めにAWS公式サイトのポイントを確認します。
--

### IAM の仕組み
IAM は、AWS アカウント の認証と認可を制御するために必要なインフラストラクチャを提供します。IAM のインフラストラクチャーは、次の図で示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/d28ad74b-eed5-75ef-888c-f091e0c834ce.png)
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/intro-structure.html
まず、人間のユーザーまたはアプリケーションがサインイン認証情報を使用して __AWS と認証__ します。認証は、サインイン認証情報を AWS アカウント が信頼するプリンシパル (IAM ユーザー、フェデレーションユーザー、IAM ロール、またはアプリケーション) と照合することによって行われます。

次に、__プリンシパルにリソースへのアクセスを許可するリクエスト__ が行われます。アクセスは、承認リクエストに応じて許可されます。例えば、コンソールに初めてサインインしてコンソールのホームページを開いたときは、特定のサービスにアクセスしているわけではありません。サービスを選択すると、承認リクエストがそのサービスに送信され、ユーザーの ID が認証されたユーザーのリストに含まれているかどうか、付与されるアクセスレベルを制御するためにどのようなポリシーが適用されているか、そして、その他の有効なポリシーがないかが確認されます。承認リクエストは、AWS アカウント 内または信頼できる別の AWS アカウント プリンシパルが行うことができます。

__承認されると、プリンシパルはユーザー内の AWS アカウント リソースに対してアクションを実行したり、操作を実行したりできます。__ 例えば、プリンシパルは新しい Amazon Elastic Compute Cloud インスタンスを起動したり、IAM グループメンバーシップを変更したり、Amazon Simple Storage Service バケットを削除したりできます。

### Principal
プリンシパルとは、__AWS リソースに対するアクションまたはオペレーションをリクエストできる人間の ID またはワークロード__ です。認証後、プリンシパルには、プリンシパルのタイプに応じて、AWS にリクエストを行うための永続的または一時的な認証情報を付与できます。IAM ユーザーとルートユーザーには永続的な認証情報が付与され、ロールには一時的な認証情報が付与されます。ベストプラクティスとして、人間のユーザーとワークロードに一時的な認証情報を使用して AWS のリソースにアクセスさせることをお勧めします。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal

次に、要点を整理します。
--
### IAMとは？
IAMは、AWSのサービスやリソースに対する __認証と認可を制御__ するサービスです。
IAMにより __誰を認証するかを制御__ 出来ます。
また、__認証されたユーザがAWSのリソースにアクセスする時、どの操作を許可するか？を管理__ することが出来ます。
(どのリソースに対するアクセスの許可や拒否を誰に付与するか)

### プリンシパルとは？
プリンシパル（Principal）は、AWS リソースに対してアクションを実行する権限を持つ主体の事です。プリンシパルの __種別としては、ルートユーザ、IAMユーザ(IAMユーザグループ)、IAMロール、フェデレーティドユーザ__ などがあります。AWS のセキュリティ認証情報を持つ個人、アプリケーション、またはサービスであり、__IAM ポリシーにおいてアクセス許可を与えられる対象__ です。


### プリンシパルの種類

**ルートユーザー**
AWSアカウント作成時にデフォルトで作成されており、アカウントのすべてのAWSリソースに完全にアクセスできる権限を持っている。

**IAM ユーザー**
AWS アカウント内で定義された個々のユーザー。
AWSのサービスやリソースに対して操作を実行する人もしくは、プログラムが使用する。
IAMユーザをまとめるのに、IAMグループを使う。

**IAM ロール**
 一時的な認証情報を提供するために使用される主体。IAM ロールは、AWS サービス、他の AWS アカウント、フェデレーションユーザー（SAML または OpenID Connect）、または IAM ユーザーに引き受けられることができます。
 
 :::note info
通常は、AWSリソースに対して権限を持たないユーザやアプリケーション等に一時的な権限を付与するためのもの。IAMロールには、長期的な認証情報は提供されておらず、代わりに一時的なアクセスキーが提供されている。IAMロールをプリンシパル等にアタッチすると、プリンシパルは、AWS STS(Security Token Service)というサービスに対して、APIコールを行い、使用期限付きのアクセスキーを取得する事が出来ます。
:::

※IAMロールのユースケース
・IAMユーザがマネジメントコンソールで使用する。
・AWSのサービスが別のAWSサービスに対して操作を実行する。

**フェデレーティドユーザー（Federated User）**
AWSアカウント外で管理、認証され、AWSのサービスやリソースに対して権限を所有する主体。
AWS アカウントに直接存在しないが、外部のアイデンティティプロバイダー（IdP）を通じて一時的なアクセスを許可されたユーザーを指します。フェデレーティドユーザーは、企業の既存の認証システム（例えば、Active DirectoryやLDAP）、サードパーティのIdP（例えば、OktaやPing Identity）、またはウェブアイデンティティプロバイダー（例えば、Amazon Cognito、Google、Facebook、Amazon）を使用して認証されます。

:::note info
プリンシパルは、IAM ポリシーの `Principal` 要素で指定されます。例えば、IAM ロールの信頼ポリシーにおいて、特定の AWS サービスがそのロールを引き受けることを許可する場合、そのサービスのサービスプリンシパル（例：`"Service": "ec2.amazonaws.com"`）を指定します。

プリンシパルは、誰が（または何が）アクションを実行できるかを定義するため、IAM ポリシーにおいて非常に重要な役割を果たします。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/5b10e809-c8d8-7e90-303e-b2404d40097d.png)



Principalの使い方を確認する
--

### IAM ユーザーをプリンシパルとして使用する例

IAM ユーザーに特定の S3 バケットへのアクセスを許可するポリシー。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::123456789012:user/ExampleUser"},
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::example-bucket/*"
    }
  ]
}
```

### IAM ロールをプリンシパルとして使用する例

特定の AWS サービス（例：AWS Lambda）が IAM ロールを引き受けることを許可する信頼ポリシー。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"Service": "lambda.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }
  ]
}
```

### AWS アカウントをプリンシパルとして使用する例

他の AWS アカウントが S3 バケット内のオブジェクトにアクセスすることを許可するバケットポリシー。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::111122223333:root"},
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example-bucket/*"
    }
  ]
}
```

### AWS サービスをプリンシパルとして使用する例

Amazon S3 が AWS CloudTrail ログファイルをバケットに書き込むことを許可するバケットポリシー。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"Service": "cloudtrail.amazonaws.com"},
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::example-bucket/AWSLogs/123456789012/*",
      "Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
    }
  ]
}
```

これらの例は、プリンシパルが AWS リソースへのアクセスを許可するためにどのように使用されるかを示しています。プリンシパルは、IAM ポリシーにおいて誰が（または何が）アクションを実行できるかを定義するために使用されます。

ロールとは？
--
ロールには、IAMロールとサービスロールがあります。

| ロールの種類             | 使用シナリオ                                                                                                                                                        |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **IAMロール（IAM Role）** | **クロスアカウントアクセス** 別のAWSアカウントのリソースにアクセスするために使用。例えば、開発アカウントから生産アカウントのリソースにアクセスする。                                                                                |
|                          | **IDフェデレーション** 外部認証情報を持つユーザーがAWSリソースにアクセスするために使用。（例えば、企業のディレクトリサービスを使用して認証されたユーザー）がAWSリソースにアクセスするためにIAMロールを使用。                                                                          |
|                          | **サービスアクセス** EC2インスタンスからS3バケットへのアクセスなど、AWSリソース間のアクセスを管理するために使用。                                                  |
| **サービスロール（Service Role）** | **AWS Lambda** Lambda関数がS3バケットのデータにアクセスするためのロール。                                                                                    |
|                          | **Amazon EC2** EC2インスタンスがDynamoDBにアクセスするためのロール。                                                                                            |
|                          | **AWS Glue** データカタログのアクセスやETLジョブの実行に必要な権限を持つロール。                                                                                 |



ロール作成の流れ
--

__1.ロールの作成__
IAM ダッシュボードで、「Roles」を選択し、「Create role」ボタンをクリックします。

__2.信頼されたエンティティの選択__

ロールの使用目的に応じて、信頼されたエンティティのタイプを選択します。例えば、AWS サービスがロールを引き受ける場合は「AWS service」を選択し、該当するサービスを選びます。

IAMロールの使用をEC2に限定する信頼ポリシーの作成画面
![EC2ロール作成画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/97e28b34-2cd0-4c62-3d89-0b00c6d98720.png)

IAMロールの使用を特定のアカウントに限定する信頼ポリシーの作成画面
![特定のアカウントのユーザを信頼するロール作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/77422f7b-ff3a-4795-bd4e-19f8160c6e0d.png)

IAMロールの使用をEC2に限定する信頼ポリシー
![IAMロールの使用をEC2に限定する信頼ポリシー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/231f3873-01a4-b404-6698-a293ae485bd4.png)

IAMロールの使用をEC2とS3に限定する信頼ポリシー
![IAMロールの使用をEC2とS3に限定する信頼ポリシー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/61ae4387-8790-75fc-e0f2-76e69db39806.png)

IAMロールの使用を特定のアカウントのユーザに限定する信頼ポリシー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/b29e66f2-5ccc-acc1-5df8-c399025b95d6.png)

__3.ポリシーのアタッチ__
ロールにアタッチするポリシーを選択します。これにより、ロールに特定の権限が付与されます。既存のポリシーから選択するか、新しいポリシーを作成できます。

アタッチするポリシーを選択
![アタッチするポリシーを選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/12df8e0e-b23c-9338-e640-0c5969b67d19.png)

信頼されたエンティティとは
--
IAMで作成したロールはユーザだけでなくサービス（s3やec2など）にも付与することができるが、その付与可能なサービスを設定しているのが「信頼されたエンティティ」の部分となる。
__この「信頼されたエンティティ」にないサービスにはロールをアタッチできない。__

IAM ロールを作成する際には、「信頼されたエンティティ」として、そのロールを引き受けることができる AWS サービスやエンティティを指定します。信頼されたエンティティは、IAM ロールの「信頼ポリシー」によって定義されます。信頼ポリシーは、特定の AWS サービスや他の AWS アカウントがロールを引き受けることを許可する JSON ドキュメントです。

たとえば、AWS Lambda 関数が Amazon S3 バケット内のオブジェクトにアクセスするために IAM ロールを引き受ける場合、そのロールの信頼ポリシーには AWS Lambda サービスが信頼されたエンティティとして含まれている必要があります。信頼されたエンティティに指定されていないサービスは、そのロールを引き受けることができません。

信頼ポリシーの例
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
このポリシーでは、lambda.amazonaws.com が信頼されたエンティティとして指定されており、AWS Lambda サービスが sts:AssumeRole アクションを使用してロールを引き受けることを許可しています。

IAMロールとポリシーを使いこなすためのポイント(2/2)
https://qiita.com/kimuni-i/items/84012c5ebfec8e6b63e2