【AWS】触って理解するIAMユーザー、ロール、AssumeRole


## はじめに

業務でほどよくAWSは使用しますが、管理側(?)は経験がありません。
AWSの認定資格の勉強でも、結構アカウント管理周りは机上の理解でした。

そこで、今回はアカウント管理で重要なAssumeRoleについて、実際に触って整理していこうと思います。

- [はじめに](#はじめに)
- [前提理解](#前提理解)
  - [IAMユーザーだけで管理する](#iamユーザーだけで管理する)
  - [ロールを使用する](#ロールを使用する)
  - [前提のまとめ](#前提のまとめ)
- [AssumeRole](#assumerole)
  - [ケース](#ケース)
  - [やってみること](#やってみること)
  - [ユーザーA](#ユーザーa)
  - [ロール1](#ロール1)
    - [信頼ポリシー](#信頼ポリシー)
    - [許可ポリシー](#許可ポリシー)
  - [ここまで](#ここまで)
  - [てことでやってみる](#てことでやってみる)
    - [ふりかえり](#ふりかえり)
    - [Switch](#switch)
    - [確認](#確認)
- [まとめ](#まとめ)

## 前提理解
ここは前提として、サクッとまとめます。

### IAMユーザーだけで管理する
誰になんの権限をもたせるか、、、複雑ですね。

```mermaid
graph TB
    subgraph AWS Account
        subgraph IAM Users
            U1[開発者A<br/>dev-user-a]
            U2[開発者B<br/>dev-user-b]
            U3[運用担当者A<br/>ops-user-a]
            U4[運用担当者B<br/>ops-user-b]
            U5[セキュリティ担当者<br/>security-user]
        end

        subgraph Individual Permissions
            P1[EC2関連の権限<br/>AmazonEC2FullAccess]
            P2[S3関連の権限<br/>AmazonS3FullAccess]
            P3[CloudWatch関連の権限<br/>CloudWatchFullAccess]
            P4[Security Hub関連の権限<br/>SecurityHubFullAccess]
            P5[Systems Manager関連の権限<br/>AWSSystemsManagerFullAccess]
        end

        U1 --> P1
        U1 --> P2
        U2 --> P1
        U2 --> P2
        U3 --> P1
        U3 --> P2
        U3 --> P3
        U3 --> P5
        U4 --> P1
        U4 --> P2
        U4 --> P3
        U4 --> P5
        U5 --> P4
        U5 --> P3
    end
```

### ロールを使用する

さて、これをロールを使用して綺麗にしていきましょう。

```mermaid
graph TB
    subgraph AWS Account
        subgraph IAM Roles
            R1[開発者ロール<br/>developer-role]
            R2[運用担当者ロール<br/>operator-role]
            R3[セキュリティ管理者ロール<br/>security-admin-role]
        end

        subgraph AWS Managed Policies
            P1[AmazonEC2FullAccess]
            P2[AmazonS3FullAccess]
            P3[CloudWatchFullAccess]
            P4[SecurityHubFullAccess]
            P5[AWSSystemsManagerFullAccess]
        end

        R1 --> P1
        R1 --> P2
        
        R2 --> P1
        R2 --> P2
        R2 --> P3
        R2 --> P5
        
        R3 --> P3
        R3 --> P4
    end
```

### 前提のまとめ

ユーザーだけで権限管理しようとするととても複雑なので、ロールごとにまとめることでシンプルになりました。

これによって
- ユーザー
  - 誰がいるか
- ロール
  - どんな案件（ロール）があるか
  - それぞれ何ができるか

が整理できました。

このユーザーとロールを紐付けるために、AssumeRoleを使用します。

では、ユーザーとロールを紐づけて、AssumeRoleの実際の動きを見ていきましょう。

## AssumeRole

### ケース
今回は同一のアカウントから行います。実際には別アカウントになったりしますね。

- ユーザーA
  - ロール1へのAssumeRoleのみ可能
- ロール1
  - ユーザーAからのAssumeRoleを許可
  - Lambdaへのフルアクセスを許可

### やってみること

以下の構成を実際にやってみます。

```mermaid
graph LR
    subgraph AWS Account
        U[ユーザーA]
        R[ロール1]
        L[Lambda]
        
        subgraph Policies
            UP[ユーザーポリシー<br/>Allow: sts:AssumeRole]
            TP[信頼ポリシー<br/>Allow: UserA]
            RP[ロールポリシー<br/>Allow: Lambda:*]
        end
        
        U -->|1.AssumeRole| R
        R -->|2.一時的な認証情報| U
        U -.->|3.Lambdaの操作| L
        
        U --> UP
        R --> TP
        R --> RP
    end
```

### ユーザーA

ユーザーAには以下のポリシーを設定しています。

詳細は省きますが、とにかくAssumeRoleしか許可していない、という意味です。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AssumeRolePolicy",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::XXXXXXXXXXXX:role/role1"
        }
    ]
}
```

前述の通り、AssumeRole以外の権限を持っていないので、ユーザーAでのログイン時には、Lambdaにアクセスできません。

![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/eeda70db-820c-e037-bf61-b6dda341c198.png)

### ロール1

続いて、ロール1には以下を設定しています。

#### 信頼ポリシー

ユーザーAからのAssumeRoleのみ許可しています。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/userA"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

#### 許可ポリシー

ここでは、Lambdaのフルアクセスを許可します。

:::note warn
この例では分かりやすさのために*FullAccessを使用していますが、実際の運用では必要最小限の権限を付与しましょう。
:::

![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/8337b7ab-0b1a-ee64-bd96-c2fedab89f18.png)


### ここまで

ユーザーAとロール1の双方で、AssumeRoleを許可する関係ができました。

```mermaid
graph LR
    U[ユーザーA] 
    R[ロール1]

    U -->|"1.このロールに対してAssumeRole可能"| R
    R -->|"2.このユーザーからのAssumeRoleを許可"| U

    note["双方向の信頼関係が必要<br>・ユーザー側：ロールへのAssumeRole権限<br>・ロール側：ユーザーからのAssumeRole許可"]
```

ユーザーとロールの両方で許可し合うことで、AssumeRoleの準備ができます。
- ユーザー側がロールへのAssumeRole権限を持っている
- ロール側がユーザーからのAssumeRoleを許可している

### てことでやってみる

では実際にやってみましょう。

#### ふりかえり

ユーザーAの状態では、Lambdaにアクセスはできません。

![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/eeda70db-820c-e037-bf61-b6dda341c198.png)


#### Switch

コンソール右上のメニューから、ロールの切り替えを選択し。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/1d73db8f-6502-a2d6-1b34-a1464ff5b258.png)


作成したロールの情報を入力します。

![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/a885088e-fbfa-2e9f-3d16-8d8833cbaf6a.png)


そうすると、ロールが変わった状態になります。

#### 確認

さきほどアクセスできなかったLambdaのダッシュボードにアクセスできました。

![image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689241/53b8b215-d696-db85-eb26-9b64c60dd530.png)


で、いつのまにかAssumeRoleからスイッチロールに変わっていましたが、実際には以下が行われています。
ユーザーがロールを使用する過程でAssumeRoleが行われます。

```mermaid
sequenceDiagram
    participant U as ユーザーA
    participant STS as AWS STS
    participant R as ロール1

    Note over U,R: スイッチロール実行時
    U->>+STS: 1. AssumeRole API呼び出し<br/>"ロール1を使わせて！"
    STS->>R: 2. 信頼ポリシーチェック<br/>"このユーザーからのAssumeRole許可ある？"
    R-->>STS: 3. OK!<br/>"このユーザーからは許可してます"
    STS-->>-U: 4. 一時的な認証情報を発行<br/>"はい、これでロール1として操作できます"

    Note over U,R: この後、発行された認証情報を使って<br/>ロール1として操作可能に
```

## まとめ

今回はAssumeRoleについてまとめました。

ユーザーとロールの構築、AssumeRoleの実際の挙動を見てきましたが、開発者の立場でアサインされることが多く
  - 現場ではアカウントを渡されて、なんとなく実施している
  - AWS認定試験では、机上の理解になっている

となりがちだったので、実際に触って整理すると、とても理解が深まりました。
同じようなふんわり理解の方々などの参考になれば幸いです。

以上です。