AWSマルチアカウントにおけるIAM運用リファクタ

スタンダードに沿った形ではあるのですが、
私が行ったIAM運用のリファクタを一例として紹介します。

# 概要

- Groupにポリシー設定を集約した
- アカウント横断できるGroupを作成した
- CS部隊のIAM管理をCS管理者に委譲した（CS:カスタマーサポート）

イメージ図
<img width="543" alt="qiita_image.png" src="https://qiita-image-store.s3.amazonaws.com/0/57750/66638798-9853-4fe7-8bef-7d4fc9238c7a.png">

# 方針と作業

前提として、以下のような状態でIAMは各アカウントで運用しているものの、
組織全体としてIAM運用の最適化は一切考慮されていませんでした。

- 6つのAWSアカウントを使ってサービスを運営している
- 複数のアカウントで、6名のサーバーエンジニアが横断して作業している
- あるアカウントで、非エンジニア5名がS3（WebHosting）を触っている
- あるアカウントで、CSメンバー約10名がいて時折出入り発生する、S3参照している

この前提や規模が違えば、リファクタの方針も変わると思います。
今回のケースは、以下のように方針を決め作業しました。

## 全メンバーをIAMでやりきる

そもそも、多くのメンバーにIAMを発行しない運用がベストです。
今時、リリース作業なんてのはCIツールに集約して任せるべきです。

ただ、CIツールが未整備なのと、CIツール導入に際して
既に走っている運用ルールの変更にはかなり神経と時間を使う必要があるため、
これは次の課題として切り出すことにしました。

順次、一部のメンバーに再発行IAMに切り替えてもらうだけに留めました。

## PolicyはGroupに集約する

User個別設定は禁止してGroupに集約させることで、Policyの見通しが良くなります。
グルーピングする必要のないユーザーでも、必ずGroupを作成して所属させます。

## クロスアカウントのGroupを作る

複数のアカウントで作業するサーバーエンジニアは、
どのアカウントにも容易に切り替えて作業できることにしました。
Userを作成する側をメインアカウント、
そのUserが振舞うRoleを作成する側をサブアカウントと呼称しています。

この手順に従って、アカウント間の準備が必要です。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/walkthru_cross-account-with-roles.html

クロスアカウントできるGroupは以下の２つに分けました。

### Administrator

全権限を持つManagedPolicyのAdministratorをアタッチしただけです。

メインアカウント側は、
サブアカウント群の同等権限Roleを集約するInlinePolicyが付きます。

```lang:CrossAdministrator
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": [
            "arn:aws:iam::sub1alias:role/Sub1AliasAdministrator",
            "arn:aws:iam::sub2alias:role/Sub2AliasAdministrator",
            ...
        ]
    }
}
```

### PowerUserExtend

IAM以外の全権限を持つManagedPolicyのPowerUserをアタッチして、
それ以外の足し引きは下記InlinePolicyで定義しました。
とりあえず現状はこうしておいて、今後必要に応じて調整していきます。

```lang:PowerUserExtend
{
    "Version": "2012-10-17",
    "Statement": [
        # ElasticBeanstalkのCLIコマンドで必要なiam系は許可する
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "iam:ListRolePolicies",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListInstanceProfiles",
                "iam:ListServerCertificates",
                "iam:UploadServerCertificate"
            ],
            "Resource": "*"
        },
        # ポータル画面は全て禁止する 
        {
            "Effect": "Deny",
            "Action": "aws-portal:*",
            "Resource": "*"
        }
    ]
}
```

メインアカウント側には、
Administratorと同様に`CrossPowerUser`のInlinePolicyも定義します。

## CSメンバーのIAM管理をCS管理者に委譲する

CSメンバーは、委託先で連携が遠かったり、出入りの頻度が高めという特性から、
AdminエンジニアにIAM編集の依頼が都度来るのは避けることにしました。

CS管理者が、既にCSのメンバーやツールアカウントの管理を行っているため、
そこにAWSのIAM管理も合わせてやってもらうのは当然の成り行きかなと思います。
権限編集の委譲ということで、検証やダブルチェックは念入りに行いました。

下記は、そのinlinePolicyです。
上位権限に所属するUserが同居していて、そこを禁止しているのですが、
ここの同期を手動で更新しないとけないのが懸念としてあります。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateUser",
                "iam:DeleteUser",
                "iam:ListUsers",
                "iam:GetGroup",
                "iam:ListGroups",
                "iam:ListGroupsForUser",
                "iam:CreateLoginProfile",
                "iam:DeleteLoginProfile",
                "iam:GetLoginProfile",
                "iam:ListAttachedUserPolicies",
                "iam:ListSSHPublicKeys"
            ],
            # 上位権限に所属する特定ユーザー以外をリソース対象とする
            "NotResource": [
                "arn:aws:iam::123456789012:user/hogehoge",
                "arn:aws:iam::123456789012:user/fugafuga"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup"
            ],
            # CSUserのみリソース対象とする
            "Resource": [
                "arn:aws:iam::123456789012:group/CSUser"
            ]
        }
    ]
}
```

# Tips

### アカウント毎にエイリアス設定しておく
IAMのダッシュボード上部で変更できます。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/console_account-alias.html
設定の随所に現れるので、アカウントID（数字12桁）だと見分けがつかなくなります。
グローバルユニークなので、サービス名やプロジェクト名などを接頭に付けました。

### 請求情報のIAMアクセス許可しておく
IAMからでも請求情報の参照を許可して、rootログインの機会を減らします。
https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/grantaccess.html

### eb cliはクロスアカウントできない

一般的なCLIは、profile指定でうまくいくのですが、
ebコマンドだけは下記のエラーが発生しました。

```
You have not yet set up your credentials or your credentials are incorrect
You must provide your credentials.
```

どうやらebコマンドはそのアカウントのUser（credential）が必要みたいです。
泣く泣く、これは従いました。