G Suiteを利用してGAMでユーザーごとの利用できるAWSアカウントとロールを管理する

[NIFTY Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nifty)　11日目の記事になります。

AWSのアカウント管理や認証をどうしていけばいいのか試行錯誤してました。
タイトルから個人的な結論が出ていますが、考えた順に書いていきます。

# 事前知識

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

マルチアカウントにする意義と、そのためのアカウント間の構成を教えてくれるので、読んだことがない方は一度こちらを読んでおくことをオススメします。

# 案1: Microsoft ADで管理してMasterアカウントにログイン後、SubアカウントにSwitch Roleする

![AWS_DirectoryService.png](https://qiita-image-store.s3.amazonaws.com/0/135041/459c45be-e491-a2b8-9dc2-d11c2eeb8e7f.png)

IDaaSやADを自前で持っていない場合は、すべてがAWSで完結するからこれが綺麗だと思う。
AWSドキュメントにこの構成を実現するためのCloud Formationのサンプルも提供されている。

* [AWS Multiple Account Security Strategy – AWS Answers](https://aws.amazon.com/jp/answers/account-management/aws-multi-account-security-strategy/)

しかし、いまだとCloud Formation StackSetsがあったり、AWS SSOが出てきたりしているので、ADを使うならもっと効率的な構成にできると思う。
AWS SSOがLDAPに対応したらまた検討してみたい。

# 案2: OpenAMをIdpとしてAWSにSAML認証でログインする

![OpenAM.png](https://qiita-image-store.s3.amazonaws.com/0/135041/349aebdb-0738-ed42-b057-8bee5ae2701a.png)

すでにLDAPを持っていて、できるだけ内部で管理したい場合の構成。

OpenAMのグループに対して、利用できるアカウントとロールを付けていく管理がいいと思うが、OpenAMがまるで詳しくないので、できそうだというところまで。

# 案3: G SuiteをIdpとしてAWSにSAML認証でログインする

IDaaSとしてはOneloginなど他にもありますが、G Suiteが試しやすかったので、こちらを採用。
G SuiteからSAML認証でAWSにログインするまでの手順は、こちらにまとまっているので、ここでは説明を割愛します。

* [G SuiteのアカウントをAWS コンソールへ連携させる \- Qiita](https://qiita.com/mossaky/items/bed0c9f3d5fb5a7be41a)

## 案3-1: MasterアカウントのIdpとして登録

![G_Suite.png](https://qiita-image-store.s3.amazonaws.com/0/135041/af78bf38-d70a-ca72-179b-6052f4152b7e.png)

案1,2と同じようにMasterアカウントを中継する構成。

G SuiteのBasicプランでも構成自体は実現できる。
ちなみにOneloginで同じことをしようと場合も無料プランで構成自体は実現できます。
ただしどちらも監査ログが取れないので、実運用する上ではもっと上位プランのほうが望ましい。

## 案3-2: SubアカウントのIdpとして登録

![G_Suite2.png](https://qiita-image-store.s3.amazonaws.com/0/135041/a6242999-c953-cee8-15b0-da3b3eb2885f.png)

Masterアカウントを中継せずに直にSubアカウントへログインする構成。

G Suiteはひとつのアプリから、下記のアカウント＋ロールにもいけるのでMasterアカウントを経由する方法を取る必要はない。

* Single APP -> Single Account Single Role
* Single APP -> Single Account Multi Role
* Single APP -> Multi Account Multi Role

G SuiteユーザーのAWS Console Roleのrole属性に　`roleのarn,Idpのarn`　の形で記載する。roleは複数値入れられるように設定されているので、別のSubアカウントの権限も与えたい場合は、これを増やしていけばいい。

![管理コンソール.png](https://qiita-image-store.s3.amazonaws.com/0/135041/a8ad7188-f5ad-75c6-bca7-67cac79ec930.png)

G Suiteのアプリを選択すると、このようにSwith Roleの選択画面に飛ぶ。

![Amazon Web Services Sign In.png](https://qiita-image-store.s3.amazonaws.com/0/135041/36314ce7-ca6b-73fb-0258-1fb6877785d9.png)


アカウントがIDなのはどうしようもなさそうだが、Role名を工夫すればどのサービスのアカウントか判別できそう。
Role名を統一したい場合は、Chromeの拡張機能とか作ってAWSアカウントIDと名前を置換するとか。
あとで困りそうだけどサービスごとにG Suiteのアプリを分けてしまう手もある。

各Subアカウントに対してIdpを設定する必要があるが、Cloud Formationでかなりの部分は吸収できるし、そもそもアカウントをそんなにぽんぽん増やすシーンも思いつかないので、その管理コストよりも利用者の日々の手間をワンステップ減らしたほうが利はあると思う。

### GAMでG SuiteのユーザーにAWSの権限を与える

人が増えたり減ったり入れ替わりが起きるごとに、G SuiteのAWS Console Roleを変更するのは辛いので自動化を目指します。
GAMを使えばG Suite APIをCLIで簡単に操作できるので、これを使います。

* [jay0lee/GAM: command line management for Google G Suite](https://github.com/jay0lee/GAM)

インストールから基本的な使い方は、以下に詳しく書いてあるので割愛します。

* [GAMでGoogleAppsのユーザー・グループ管理を楽にする \- Qiita](https://qiita.com/W_Yoshida/items/5dffdc87846e9a689036)

今回修正がしたいのはCustom User Schema Fieldなのでマニュアルはこれ。

* [GAM3DirectoryCommands · jay0lee/GAM Wiki](https://github.com/jay0lee/GAM/wiki/GAM3DirectoryCommands#setting-custom-user-schema-fields-at-create-or-update)

試しにさっきのユーザーを `54321` をなくして、 `33333` をいうAWSアカウントIDに権限を付けてみます。
注意点としては追加削除という概念はないため、指定したものを上書きする形で指定します。

```shell-session
# gam update user username@example.com \
AWS_Console_Role.role multivalued arn:aws:iam::12345:role/CrossAccountManager-Administrator,arn:aws:iam::12345:saml-provider/G-Suite \
AWS_Console_Role.role multivalued arn:aws:iam::33333:role/CrossAccountManager-Developer,arn:aws:iam::33333:saml-provider/G-Suit
updating user username@example.com...
```

![管理コンソール2.png](https://qiita-image-store.s3.amazonaws.com/0/135041/bbefb677-636c-86cb-f5b3-c0ab676cf3ee.png)

ちゃんと更新できてますね。

### 自動化について

ユーザーごとに管理するのは大変なので、グループごとにアカウントとロールを管理して、そのマスターが更新されるかグループのメンバーが更新されたら、functionが起動してグループ内ユーザーのroleを更新してくれる的なものまでいければ完璧ですが、まだ試していないので今回はここまで。