15分で教えるAWSの複数アカウント管理

AWSアカウントの分け方や複数アカウントの管理方法を教える機会があったので書いた記事です。
管理上もっとやることが多いと思いますが、目立ったところを教えるために書いています。

# なぜアカウントを分ける必要があるのか

![AWS におけるマルチアカウント管理の手法とベストプラクティス.png](https://qiita-image-store.s3.amazonaws.com/0/135041/40f8bf81-cbb4-6ed2-fdfd-474a2ddf21fc.png)

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

上記スライドにすべて書いてありますが個人的な意見も交えてると、アカウントを分ける基準は `コスト` と `環境` と `役割` の３つ。

- `コスト`
  - アカウント単位で分ければタグによるコスト配分をしなくてよくなる
  - プロダクト単位や環境単位で正確なAWS費用を出せる
- `環境`
  - オペミスを防ぐためにも本番と開発ではアカウントを分けたほうがいい
  - 分けていると開発やテスト時は多少雑な IAM 管理でも許される
- `役割`
  - コスト配分先が同じでも、利用者が異なっていてシステム上分けることが可能ならアカウントを分けたほうが IAM の権限管理が複雑化しにくい
  - 全アカウントに対してなにかを行うアカウントは強い権限を持つため分けたほうがいい

## アカウント分割粒度例

実際に分けてみた例が以下のもの。

- `一括請求用`
  - Organization の管理アカウント
- `全アカウントに対してアクションを行うもの`
  - セキュリティアカウント
  - 監視アカウント
  - 監査アカウント
  - ログ集約アカウント
- `多くのサービスが利用するもの`
  - サービス向け認証基盤アカウント
  - サービス向け決済基盤アカウント
  - 自社向け認証基盤アカウント
- `サービス＆環境単位`
  - ほげほげサービスアカウント（Production）
  - ほげほげサービスアカウント（Development）
  - ほげほげサービスアカウント（Staging,Test などなど）
- `小さくて集約したほうがいいサービス向け`
  - CloudFront+S3 構成のみアカウント
  - WordPress 構成サービスアカウント

組織の規模によっては、ここまで分ける必要がないが一度書き出して分けてみて、各アカウントで入る人や持つべき権限が同じようなものがあれば合体させるといいと思います。

# 複数あるアカウントはどう管理していけばいいのか

## [AWS Organizations](https://aws.amazon.com/jp/organizations/)

規模の大きな組織になると AWS アカウントが数百になったりしますが、AWS には一元管理する方法が用意されています。

- 請求の一元化
- Service Control Policies による利用制限
- AWS アカウントの作成、招待
- 組織内のアカウントに対してのタスク実行と情報集約

参考：[AWS Organizations の用語と概念 \- AWS Organizations](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_getting-started_concepts.html)


AWS Organizations を使うと AWS アカウント間で親子関係を構築することができます。
ただし親となれるアカウントは１つのみで、子が複数の親を持つことはできません。また子が孫にあたるアカウントを持つこともできません。


## [AWS Control Tower](https://aws.amazon.com/jp/controltower/)

AWSが推奨する複数アカウント管理に必要なものが揃った環境を一発で作れるサービスです。

新規でAWSアカウントを取ったばかりだったり、Organizationをまだ作っていない場合は Contorl Tower を利用して複数アカウントの管理を行うのをおすすめします。

Contorl Tower の Landing Zoneがやっていることが多すぎるので以下のリンク先を参照してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/7f6b58e8-9d26-195f-4ed7-d7adf1335abe.png" width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/84e77411-bcc0-c87d-d617-c00b6453af25.png" width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/c69c4a4e-5582-367b-c0bd-dade651d8982.png" width=25%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/645bd27a-17f1-480c-2b8b-6b85d067cc83.png" width=25%>

参考：[Landing Zone \| AWS Solutions](https://aws.amazon.com/jp/solutions/aws-landing-zone/)
参考：[AWS Control Tower の仕組み \- AWS Control Tower](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/how-control-tower-works.html)

これだけの初期設定を自前で用意するのはかなり大変なので、Landing Zone がデフォルトで作るものに邪魔なものがあったとしても Landing Zone で作っておいたほうが速い場面が多いと思います。

### Contorl Tower を使わない方がいいケース

[よくある質問 \- AWS Organizations \| AWS](https://aws.amazon.com/jp/organizations/faqs/)	
> AWS Control Tower と AWS Organizations の違いは何ですか?
>
> AWS Control Tower は複数の AWS のサービス (AWS Organizations を含む) を抽象化して、セキュアな Well-Architected 環境の設定を自動化します。AWS ベストプラクティスを使用してマルチアカウント環境を自動的にデプロイする場合は、AWS Control Tower が最適です。高度なガバナンスおよび管理の機能を備えた独自のカスタムマルチアカウント環境を定義したい場合は、AWS Organizations をお勧めします。

~~まだ4リージョンだけの対応ですし~~ Guardrails を自分で作ることもできません。
時期尚早な面もありますので、独自に同様な環境を構築できるのならば、そちらのほうがコントロールはしやすいと思います。

**2021/04/09追記：**
[AWS Control Tower が東京リージョンでご利用いただけるようになりました \| Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/aws-control-tower-tokyo/)

東京リージョンでControl Towerを使えるようになったので、AWS Service Catalogなどリージョン単位のサービスは使いやすくなりますね。


### 既存 Organization で Control Tower を利用する

Organization がすでに作られていると Control Tower を利用できませんでしたができるようになりました。

- [Plan Your AWS Control Tower Landing Zone \- AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/planning-your-deployment.html#deploy-with-existing-orgs)

ログ保存用・監査用のアカウントが新規で作成されて、Landing zone が適用された新規 Core OU が作成されます。
既存アカウントはまだ Control Tower 管理下にはならず影響は与えません。
管理下に置きたい場合は後述の設定を入れる必要があります。

### 既存アカウントを Control Tower 登録済みアカウントにする

Control Tower 管理下で作成されていないアカウントは、　Control Tower が利用されている Organization の下にあっても Control Tower 登録済みアカウントにはなれなかったのですが、それが可能になりました。

- [既存のAWSアカウントを AWS Control Tower へ登録する \| Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/enroll-existing-aws-accounts-into-aws-control-tower/)
- [Enroll existing AWS accounts into AWS Control Tower \| AWS Field Notes](https://aws.amazon.com/jp/blogs/field-notes/enroll-existing-aws-accounts-into-aws-control-tower/)
- [Enrolling an Existing AWS Account in AWS Control Tower \- AWS Control Tower](https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide//enroll-account.html)

いくつか管理下に置くために設定と条件はありますが、そこまで厳しいものではないので既存アカウントがあって Control Tower で統一管理できないと諦めていた方はこちらを実行してみるとよいでしょう。

# 複数アカウントで行動を制御したい

## [Service Control Policies](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_manage_policies_scp.html) による利用制限

AWS Organizations としての親は１つしか持てませんが、組織内のアカウントで権限的な階層を作ることはできます。

Organization Unit(OU) という単位に Service Control Policies(SCP)を設定することができて、OU に属する `AWSアカウントレベル` の機能を制限できます。
OU は階層構造を持つことができ SCP は子の OU にも影響を与えます。
AWS アカウントが所属できる OU は１つのみです。

下記の例だとブラックリスト方式で制限をかけています。

![OrganizationSCP.png](https://qiita-image-store.s3.amazonaws.com/0/135041/ac8a78ca-bdb7-bdfd-a431-60be35ee44ac.png)

個人的に SCP の一番の利点だと思うのは、AWS アカウントのルートユーザーも制限の対象として含まれる点です（一部制限できない操作はあり）。
例外として考えなくてはいけなかったルートユーザーの不正利用を制限できるため、SCP で制限してしまえば監視する必要がある項目が減ります。
使う予定の機能が定まっているのならばホワイトリスト方式のほうがセキュアです。

※Organizationの管理アカウントはSCPの影響を受けないため、管理アカウントにはOrganizationと請求以外の役割はあまり持たせないようにしましょう

~~一見便利な SCP ですが IAM の Policy ほど柔軟性はありません。~~
~~Resource は `*` しか使えない上に Condition もなく、Principal も指定できません。~~
~~Service と Action を制限するものだと思って使いましょう。~~

**2019/07/30追記：**
Resource の指定や Conditon も使えるようになっていました。Wildcard も使えます。
Config Rule に頼る部分が減るため費用削減にもなりますし、よりセキュアにできます。

参考：[AWS Organizations のサービスコントロールポリシーで、きめ細かなアクセス許可管理が可能に](https://aws.amazon.com/jp/about-aws/whats-new/2019/03/service-control-policies-enable-fine-grained-permission-controls/)
参考：[サービスコントロールポリシー \- AWS Organizations](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_manage_policies_scp.html)

## [IAM Permissions Boundary](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)

SCP でアクション縛って利用者はIAMの権限変更できないようにして最小権限の原則に従うぞ！と息巻いても運用が回りません。
誰でも柔軟に各アカウントで権限のポリシーの付け替えができるようにしたいが過剰に付けられたくない、というときに使うのが IAM Permission Boundaries。

1. 絶対禁止したいものを SCP で定義
2. 各アカウントのIAM管理者が Permission Boundary で利用者の権限範囲を定義
3. 利用者は Permission Boundary で定義された範囲のポリシーのみ利用できる（範囲外の権限を付けても無効）

SCP の管理者から各アカウントのIAM管理者へ権限管理の委任を行えます。

![20190129 AWS Black Belt Online Seminar AWS Identity and Access Manage….png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/8c65b9d4-972d-d1e0-3a7c-ca35835d958f.png)
![20190129 AWS Black Belt Online Seminar AWS Identity and Access Manage… (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/ea8fa6fc-bc0f-9986-3b00-3778626884d6.png)

参考：[20190129 AWS Black Belt Online Seminar AWS Identity and Access Manage…](https://www.slideshare.net/AmazonWebServicesJapan/20190129-aws-black-belt-online-seminar-aws-identity-and-access-management-iam-part1)


# 複数アカウントで同じ環境を作りたい

## AWS Organizations によるタスク実行

Organization の組織内のアカウントに対して共通の設定を入れ込むことができます。
共通で入れ込んだ設定は編集不可となっているため便利です（すべて編集不可になっているかは未確認）

ただすべてのサービスの設定ができるわけではなく一部のサービスでのみ利用できます。

[AWS Organizations で使用できる AWS のサービス \- AWS Organizations](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_integrated-services-list.html)

後述する CloudFormation StackSets と Service Control Policy を使えば同じことができるので、 Organizations でサポートされていないサービスの設定はこれらを使って反映させていくといいでしょう。

## [CloudFormation StackSets](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html)

アカウントの初期設定をしたり、初期テンプレートリソースをばらまくのに使えるサービスです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135041/a04352c8-4372-768f-3529-6ff26c18dd95.png)

参考：[AWS CloudFormation StackSets の操作 \- AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/stack_set_conceptual_sv.png)

CloudFormation(CFn)は１アカウント内の AWS リソース構成管理としてしか使えませんでしたが、CloudFormation StackSets が出たことで、複数アカウントの AWS リソースの構成管理に使うことができます。

> [StackSets の制約事項 \- AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-limitations.html)
> 管理者アカウントでは最大 20 個のスタックセットを、そして各スタックセットに最大で 500 個のスタックインスタンスを作成することができます。

~~便利な機能なのですが、少々厄介なのがこの制約。~~
~~20 個しか StackSet を作れないので、1 セットに複数の役割を持たせたり StackSets でデプロイするのと、それ以外の方法でデプロイするので分けたりが必要になってくる。~~
~~また nest した StackSet を数百アカウントにデプロイすると 500 個のスタックインスタンスを超えることがあるので、そこも注意が必要。~~

**2019/10/24追記：**
[AWS CloudFormation で StackSets の引き上げられた上限をサポート開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/08/aws-cloudformation-now-supports-higher-stacksets-limits/)	
デフォルト上限が引き上げられてました。申請すればさらに上限を上げられるみたいです。
以前の上限だとControl Towerを普通に使っていったらすぐに達してしまうので、それを対処するために上げたのかもしれません。

```
StackSet: 20 -> 100
StackInstance: 500 -> 2000
```

## AWS Config 適合パック

複数のAWS Configルールと修復アクションをまとめてデプロイできます。
AWS Config用のCloud Formationみたいなものです。

[AWS Config 適合パックの紹介 \| Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/aws-config-conformance-packs/)
[Conformance Packs \- AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/conformance-packs.html)

適用できる単位は下記パターンのみでOU単位では適用できません。

- 単一アカウント & 単一リージョン
- Organization内の全アカウント & 単一リージョン

OU単位で適用したい場合は CloudFormation StackSets を使ってカスタムリソースで設定を入れるしか現状はないと思います。


# 複数アカウントの監視・監査の情報を集約したい

## [CloudTrail](https://aws.amazon.com/jp/cloudtrail/)

AWS API の呼び出しログが記録されます、コンソールの操作も API 呼び出しに相当するため、AWS への操作ログはこの CloudTrail を見ればだいたい把握できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135041/a7ddf7f6-3b91-a00f-1af5-1f51c0a7aa9d.png)

参考：[AWS Black Belt Online Seminar 2016 AWS CloudTrail & AWS Config](https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2016-aws-cloudtrail-aws-config)

監査ログの保存先を別アカウントの S3 にできるので、すべてのアカウントのログを１つの S3 バケットに集約することができます。

## [AWS Config Aggrigator](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/aggregate-data.html)

監査やコンプライアンスチェックで使う AWS Config を集約するサービスです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/135041/703fc3eb-02cd-556f-0849-8effb8a808d1.png)

参考：[マルチアカウントマルチリージョンのデータ集約 \- AWS Config](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/aggregate-data.html)

AWS Config で監査やコンプラチェックをしていても、個々のアカウントで状態を見るか通知を飛ばして把握するしかなかったですが、Aggrigator を使うと Organization の 管理アカウントにて AWS Config の結果を集約して閲覧することができます。

特定のアカウントを Config の集約アカウントにもできます。ただし各アカウントの各リージョンで集約したいアカウントに対して Aggrigate の承認を行う必要があります。先述した CloudFormationStackSets で入れ込むといいでしょう。

Config Rule にかかった個別のリソースを見るには、個々のアカウントにログインしないといけないのが、ちょっといまいちですが、結果だけでも集約して見ることができるのはありがたいです。
機能自体は大変すばらしいのですが、 ~~1つの Rule に `$2` かかるのが最大の難点~~。

**追記(2019/07/10):**
2019/8/1からConfig Ruleの価格体系が変わるので、もっと気軽に使えるようになります！
[料金 \- AWS Config \| AWS](https://aws.amazon.com/jp/config/pricing/)

**追記(2021/01/22):**
Organization の管理アカウントでないと Aggrigator に組織単位で集約できなかったですが、管理アカウントから委任されたアカウントでもできるようになりました。
（ただ私の環境では権限がないと言われてうまくいかなかった。。なにか足りないのかな） 
[Setting Up an Aggregator Using the AWS Command Line Interface \- AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/set-up-aggregator-cli.html#register-a-delegated-administrator-cli)


## [GuardDuty](https://aws.amazon.com/jp/guardduty/)

監視で使われる GuardDuty も AWS Config のように通知を集約することができます。

![guardduty](http://image.slidesharecdn.com/20180509aws-blackbeltamazon-guardduty-180509123434/95/slide-39-1024.jpg)

参考：[20180509 AWS Black Belt Online Seminar Amazon GuardDuty](https://www.slideshare.net/AmazonWebServicesJapan/20180509-aws-black-belt-online-seminar-amazon-guardduty)

~~Organization の機能で組織の全アカウントに対して有効化と集約ができればよかったのですが、残念ながらまだできないようです。~~

**追記(2021/01/22):**
Organization の機能で組織の全アカウントに対して有効化と集約ができるようになりました（ただしリージョンごとに設定が必要）
Organization の管理アカウントだけでなく委任すれば他のアカウントでも実行できます。
[Managing GuardDuty accounts with AWS Organizations \- Amazon GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_organizations.html)

GuardDutyのS3保護がGAされてからはデフォルトでS3保護が有効化されます。
これも Organization の管理アカウントから制御可能です。

--

GuardDuty の全アカウント全リージョン有効化＋集約アカウントに対しての承認まで一気にやってくれるスクリプトが Github で公開されているので、これを叩くだけで集約させることができます。
結構時間かかるので複数アカウント一気に有効化しようとすると Lambda の実行時間上限に引っかかります。
集約するアカウントは自分で選択できます。

参考：[Amazon GuardDuty で AWS アカウントを管理する \- Amazon GuardDuty](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/guardduty_accounts.html)
参考：[aws\-samples/amazon\-guardduty\-multiaccount\-scripts: This script automates the process of running the GuardDuty multi\-account workflow across a group of accounts that are in your control](https://github.com/aws-samples/amazon-guardduty-multiaccount-scripts)