AWS アカウント・ユーザ設計について

## はじめに

皆さまごきげんよう。産2 の yu-yama＠池袋本社9F です。

AWS を利用してインフラを作るにあたり、1 アカウントで開発/結合/本番環境を作ろうとはしていませんよね。
運用へ向けてつらくならない構成を紹介します。参考にしていただますと幸いです。

## 対象者

AWS でインフラを作ってくれと言われたんだけど、何から手を付ければよいか分からない人

## TL;DR

1. AWS アカウントは用途・環境別に作成する
1. IAM ユーザはログインユーザ管理用アカウントのみに作り、各環境へはクロスアカウントロールを使用してアクセスさせる

## 用語の整理

まず用語から整理します。

1. AWS Organizations
   - 複数のアカウントを管理し、アカウント群の管理を一元的に行うサービス
   - Organization の単位で請求をまとめることができる
   - 1 つのマスタアカウントで Organization は 1 つしか作れない
   - その中に複数の Organization Unit を作成する

1. OU(Organization Unit)
   - 複数の子アカウントを束ねる論理グループ

1. AWS アカウント
   - 契約の主体となるユーザ
   - 日頃のオペレーションでは使用しないこと

1. IAM ユーザ
   - AWS のサービス(EC2, RDS, S3 など)を管理するユーザ
   - 日頃のオペレーションで使用する
   - AWS アカウントと混同するため、IAM アカウントとは呼ばない

1. IAM ポリシー
   - 権限を記述したルール集

   1. 管理ポリシー  
      「ポリシー」単体として存在できて、複数のプリンシパルエンティティ(ユーザーまたはロール)に付け外しができる

      1. AWS 管理ポリシー
         - あらかじめ AWS によって用意されている管理ポリシー。大まかに各 AWS サービスごとにフル権限と読み取り権限が用意されている。
      1. カスタマー管理ポリシー
         - 利用者が独自に作成する管理ポリシー。ジェネレータで作成するか手書きで作成する。

   1. インラインポリシー  
      「ポリシー」単体では存在できず、プリンシパルエンティティ(ユーザーまたはロール)と 1 対 1 の関係にある。

1. IAM グループ
   - IAM ユーザーをまとめるもので、役割別にグループを作る
   - ユーザは複数のグループに所属することが出来る
   - グループに対してポリシーをアタッチして使用する

1. IAM ロール
   - AWS のサービスに対して権限を付与する

## AWS アカウントの管理

以下の理由から**環境**と**用途**で AWS アカウントを分ける

1. セキュリティ
   - リソースへのアクセス制御がシンプルになる
   - マネジメントコンソール上での閲覧範囲を制限できる
     - 単一の AWS アカウントに複数のシステムを構築した場合、コンソール上で全ての AWS リソースを閲覧でき、セキュリティ上のリスクが発生する

1. 運用性
   - アカウントを分割することで、システムや環境に発生した AWS 利用費を、アカウントごとに区別して確認できる

1. 拡張性
   - AWS リソースの有効活用
     - リソースには、作成できる上限の個数が決められており、1 アカウントにした場合、有限なリソースを取り合うことになってしまう

### アカウント分割(例)

| アカウント名 | 用途                                                                  |
| ------------ | --------------------------------------------------------------------- |
| ROOT         | AWS Organization 環境 以下全ての環境を集約する                        |
| PROTO        | プロトタイプ環境                                                      |
| DEV          | 開発環境                                                              |
| STG          | 結合環境                                                              |
| UAT          | ユーザ受け入れ環境                                                    |
| PRD          | 本番環境                                                              |
| CI/CD        | CICD 環境(ECR やドキュメント格納用 S3 などを入れる)                   |
| JUMP         | ログインユーザ管理用 このアカウントを経由して各環境にログインを行う。 |
| LOG          | 各環境のログを集約する                                                |

#### AWS アカウント追加時、とりあえず以下は設定しておく

#### AWS Config
- 各種リソースの設定変更を記録できる。例えば、いつどのように Security Group を変更したか、いつ EC2 を立ち上げたか、時系列で確認できる

#### AWS CloudTrail
- AWS アカウントのガバナンス、コンプライアンス、および運用とリスクの監査を行えるように支援するサービス。

#### Amazon GuardDuty
- 悪意のある操作や不正な動作を継続的にモニタリングする脅威検出サービスで、AWS アカウントとワークロードを保護します。

---

## IAM ユーザーの管理

以下の理由から **IAM ロールによるクロスアカウントアクセス方式**を採用する

1. 1 つの環境でユーザを管理できる
1. 利用者がアカウントを切り替える際にはロールをスイッチすればよく、ログインし直しが不要
1. ロールで権限を管理するため、複数ユーザの権限のコントロールが容易

### クロスアカウントイメージ図

![クロスアカウントイメージ_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/f7c7fc30-c36d-6114-cc60-d0375fe27b5d.png)

- IAM ユーザーを作成するのは原則 Jump アカウントのみとする
- Jump アカウントのユーザに対し各環境用の IAM ロールを紐づける
- Jump アカウントのユーザは各環境へクロスアカウントアクセス(スイッチロール)して操作する

#### スイッチ先アカウント作成 ～ Jump アカウントへの紐づけ手順

例) DEV アカウントを作成し Jump アカウントに紐づける

##### DEV アカウント作成＠ROOT アカウント

ROOT アカウントで DEV アカウントを作成する

1. AWS Organization アカウントの追加 から DEV アカウント作成
1. アカウント ID を控える
1. ROOT アカウント
   1. アカウントの整理 -> 移動から Dev 領域に移動しておく

##### スイッチ先(DEV アカウント)にログインし、ルートアカウント設定、IAM ユーザ作成

1. ルートアカウントを使用してサインインから パスワードをお忘れですか で入る

1. IAM サービスから

   1. ルートアカウントの MFA を有効化

1. IAM ユーザ作成

   1. セキュリティ
      IAM セキュリティステータスがオールグリーンになるまで設定する

1. IAM ユーザでログイン

   1. IAM に MFA を設定する

##### スイッチ先(DEV アカウント)でロールを作成

1.  接続先のアカウントにてスイッチ元に権限移譲するロールを作成

    1.  ロールの作成

    1.  別の AWS アカウントにて スイッチ元のアカウント ID 入力

    1.  新しいロールにアタッチするポリシーを選択

    1.  URL を控える
        - https://signin.aws.amazon.com/switchrole?roleName={ロール名}&account={DEVアカウントID}&displayName={ロール名}@{環境名}

        ![displayName.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/04d0f04e-4bfe-6ac1-2c57-504f4e75e90d.png)
        ※ スイッチロール遷移先リンクのパラメータに displayName を追加しておくとユーザ名に表示されて分かりやすい

    1.  ロール ARN を控える
        - arn:aws:iam::{DEV アカウント ID}:role/{ロール名}

##### スイッチ元(Jump アカウント)でスイッチ先ロールへのスイッチ権限を与える

1. スイッチロール許可ポリシー作成
  - アカウント/IAM ロールにかかわらずスイッチを許可したい場合は、リソース名をワイルドカードで指定する

  ```json
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": ["sts:AssumeRole"],
        "Resource": ["*"]
      }
    ]
  }
  ```
  - スイッチできるロールを制限したい場合は Resource に ARN を設定する

  ```json
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": ["sts:AssumeRole"],
        "Resource": ["arn:aws:iam::{DEVアカウントID}:role/proto-cross-accounts"]
      }
    ]
  }
  ```

1. グループを作成し、作成したポリシーを追加する

1. グループに IAM ユーザを追加

---

##### クロスアカウントアクセスして確認

1.  Jump 環境 にログイン

    https://{JumpアカウントID}.signin.aws.amazon.com/console

- Jump 環境 → DEV 環境 にクロスアカウントアクセス
  - 権限移譲するロールを作成したときに控えたリンク先を打つ
  - https://signin.aws.amazon.com/switchrole?roleName={ロール名}&account={DEVアカウントID}&displayName={ロール名}@{環境名}

## 最後に

アカウントの分割や IAM ユーザの管理方法は後になればなるほど変更しづらくなるため、最初に方針を決めて進めるのがおすすめです。

また、 AWS Organizations を利用して複数のアカウントを管理するのですが、今からだと [AWS Control Tower](https://aws.amazon.com/jp/controltower/)から設定を進めたほうが良さげ。
記事執筆時点で東京リージョンにまだきていないし試せていません。(言い訳)

では。

## 参考リンク

- [AWS におけるマルチアカウント管理の手法とベストプラクティス](https://d0.awsstatic.com/events/jp/2017/summit/slide/D4T2-2.pdf)
- [AWS Control Tower](https://aws.amazon.com/jp/controltower/)