【AWS】複数のAWSアカウントを管理するためにStackSetを活用する #1/2【Multi Accounts】

# はじめに
AWSを活用している企業のでは多くの場合、複数のAWSアカウントを取得・運用していると思います。数が増えれば増えるほど管理が煩雑になってくると思います。
管理の仕方は様々あると思いますが、本稿では最低限こうしておけば何とかなる、という観点でのベストプラクティスを紹介します。
なお本稿において、CloudFormationという名称をCFnと略すことがありますのでご留意ください。

この記事は全部で2部構成となります。
[【AWS】複数のAWSアカウントを管理するためにStackSetを活用する #1/2【Multi Accounts】](https://qiita.com/tmiki/items/6a72b9ce67ed0a85e243)　**←いまココ**
[【AWS】複数のAWSアカウントを管理するためにStackSetを活用する #2/2【Multi Accounts】](https://qiita.com/tmiki/items/aca0f1b549fd8723d38e)

# TL;DR
- 全AWSアカウントでCloudFormation StackSetを使えるようにしておけばとりあえず何とかなる
- AWS Organizationsには、実運用上必要な管理機能が少ない
- AWS Control Towerは人類にはまだ早い気がする


# 基本的な考え方
AWSアカウントを管理する上で考えるべきことはたくさんあります。
CloudTrailsでAWS APIの実行ログを取得・安全な場所に保存する、least privilegeの原則に基づき必要なユーザに必要な権限を付与する、などなど。
挙げていったらキリがないのですが、管理対象AWSアカウントに任意のAWSリソースを確実に作る／設定する／削除する、という手段が無いことには始まりません。
本稿ではこれにフォーカスします。

マルチアカウントに関するベストプラクティスとしては下記の資料にまとまっていますので、敢えて同様の内容を記述することはしません。

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


CloudFormationにはStackSetsという機能があり、これは複数のAWSアカウントに対して同一のStackを作成できる機能になります。
この機能を活用することで、保有しているAWSアカウントすべてに対し、必要なAWSリソースを作成／削除できます。
StackSetを作るためには、対象のAWSアカウントに必要なIAM Roleを作っておく必要がありますが、これさえ済ませておけば、あとはどうとでもなります。

AWS Control Towerというサービスがつい最近リリースされましたが、
AWS Organizationsに参加済みのAWSアカウントには適用できないことから、既存のAWSアカウントに適用するのはかなり難しいものとなります。
そのため、本稿ではAWS Control Towerについては概要を確認するにとどめます。


# CloudFormation StackSets
## 概要
概要は上述した通りで、複数のAWSアカウントに対し、同一のStackを作成することができます。

Working with AWS CloudFormation StackSets - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html

以下からその仕組みを説明します。

StackSetの構成要素の図をもとにしながら、重要な概念をそれぞれ説明します。
![stack_set_conceptual_sv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137777/e56eb15d-7cf5-fea1-09f5-816242c6569d.png)


- Administrator account
    - Stack setを作成するAWSアカウント
    - 原則として、Stack setに関する作成／更新／削除作業は、このAWSアカウントのみが対象となる
    - StackSet用のIAM Role (**AWSCloudFormationStackSetAdministrationRole**) は事前に手動で作っておく必要がある
    - **AWSCloudFormationStackSetExecutionRole** のRole名は固定（他のRoleを指定して利用することはできない）
- Target account
    - Stack setに基づき、実際のCFn Stack（Stack Instance）が作成されるAWSアカウント
    - StackSet用のIAM Role (**AWSCloudFormationStackSetExecutionRole**) は事前に手動で作っておく必要がある
    - **AWSCloudFormationStackSetExecutionRole** のRole名は固定（他のRoleを指定して利用することはできない）
- Stack Set
    - Administrator accountに作成される、Stack setの設定
    - ただしAdministrator account自身には、指定しない限りは実際のCFn Stack及びAWSリソースは作らない（Administrator account自体をTarget accountとすることは出来、この場合はその限りではない）
    - 利用するCFn templateは、通常のものと違いがない
    - CFn templateへのparameter設定も、通常のそれと違いがない
- Stack Instance
    - Administrator accountで作成されたStack setをもとに、各Target account上で作成されるCFn Stack
    - Target accountにAWS Management Consoleでアクセスすると、CloudFormationのDashboardから参照できる
    - 実体として、「StackSet-{{StackSet名}}-{{ランダム文字列}}」といった名称のCFn Stackとして生成されている


## CFn StackSetによる、Target accountへのStack作成の仕組み
上記公式ドキュメントからだけでは、どのAWSアカウントのどのIAM RoleがどのタイミングでAssumeRoleされていくかわかりにくいので、以下に整理します。
具体的な動作は以下のようになります。

1. 全AWSアカウントに作成したいAWSリソースを定義したCFn templateを作成し、Administrator account上でStack setを作成する。併せて、Target account上にStack instanceを作成する。
2. Administrator accountのCloudFormationサービスは、 AWSCloudFormationStackSetAdministrationRole をAssumeRoleする。
3. AWSCloudFormationStackSetAdministrationRole をAssumeRoleしたのち、各Target accountの AWSCloudFormationStackSetExecutionRole をAssumeRoleする。
4. 各Target accountの AWSCloudFormationStackSetExecutionRole の権限で、CFn Stackを作成する。

これを図示すると下記のようになります。

![AWSMultiAccounts_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137777/4d9867a2-3f41-261c-4722-761d05d00495.png)

公式ドキュメントのチュートリアルを試すと、よく理解できるようになります。

Prerequisites: Granting Permissions for Stack Set Operations - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs.html

Getting Started with AWS CloudFormation StackSets - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-getting-started.html


# その他関連するAWSサービス
## AWS Organizations

複数のAWSアカウントを管理することができます。出来ることは概ね以下の3つです。

- 簡単に新たにAWSアカウントを作成することができ、また作成されるAWSアカウント上に管理用のIAM Role（※）を作成することができる
- 作成されたAWSアカウントの請求は、masterアカウントにConsolidated Billingされる
- OCP(Organization Control Policy)/SCP(Service Control Policy)を定義することで、各AWSアカウントで実行できるAWS APIを制御することができる

実運用上、各組織において必要なIAM Roleは、開発者用や管理者用、Billing確認用など何パターンかあると思います。AWS Organizationsには残念ながら、全AWSアカウントに対して必要なIAM Roleを作成する、といった機能はありません。CloudFormation StackSetを使え、ということなのでしょう。


※管理用のIAM Roleは、任意の名前を指定することができますが、そのPolicyの内容を指定することは出来ません。Permissions、Trust Relationshipsは下記の内容が設定されます。
Permissionsは、「AdministratorAccess」という名称のInline policyとして付与されます。

```json:Permissions
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
```

Trust Relationshipsは、masterアカウントのIAM EntityであればAssumeRole出来る権限が付与されます。（下記例では、AWSアカウントIDが123456789012となっている個所に、実際のmasterアカウントのAWSアカウントIDが入ります。）

```json:Trust&nbs;Relationships
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```


公式ドキュメントは下記にあります。

What Is AWS Organizations? - AWS Organizations
https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html

## AWS Control Tower
つい最近、AWS Control Towerという機能がリリースされました。これも複数のAWSアカウント管理を支援するためのサービスです。後述する「AWS Landing Zones」を実装したサービスで、AWS Organizationsを超強力にしたものと思えば良いでしょう。
AWS Control Towerをきちんと使いこなすためには、AWS Landing Zonesの理解は必須です。

概ね以下のことが行われます。

- 運用上便利になること
    - Account Factoryと呼ばれる機能で、AWSアカウントを簡単に新規作成できるようになる
    - AWS SSOが自動的に設定され、全AWSアカウント用のManagement Console用のポータルが生成される
- セットアップ時に行われること
    - ログ収集用のAWSアカウント(Log archiveアカウント)、セキュリティ用のAWSアカウント(Auditアカウント)が必ず新規に作成される
    - GuardDutyでの検知内容を通知するためのSNS Topicが、Auditアカウントに生成される
    - GuardRailと呼ばれるポリシーの集合体がデフォルトで定義され、全AWSアカウントに強制されるようになる。GuardRailの実態は、SCP／AWS Config Rulesの集合体。
- AWSアカウントの新規作成時に行われること
    - 全AWSアカウントでCloudTrailが有効にされ、ログはLog archiveアカウントに集約される
    - 全AWSアカウントでAWS Configが有効にされ、ログはLog archiveアカウントに集約される
    - 全AWSアカウントでAWS Config Rulesが有効にされ、違反の検知内容はAuditアカウントに集約される？（未確認）
    - 全AWSアカウントにGuardDutyが設定され、検知内容はAuditアカウントに集約される
    - GuardRailsが強制的に適用される。
- OUの概念
    - Root OU/Core OU/その他OUの3種類がある
    - masterアカウントはRoot OUに所属する
    - Log archiveアカウントとAuditアカウントはCore OUに所属する
    - その他のAWSアカウントは任意のOUに所属させることができる

ただし、既にAWS Organizationsに所属しているアカウントを参加させるのが難いこと（不可能ではないが、大変）、SCPを既に活用している場合は競合することなどから、適用が難しいケースがあると思います。

個人アカウントでいろいろ試していましたが、意外とAWS Configの費用が嵩むので削除してしまいました。お陰でいくつか詳細未確認な箇所があります、すみません。

公式ドキュメントは下記にあります。

What Is AWS Control Tower? - AWS Control Tower
https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html

## AWS Landing Zones
AWS Control Towerのベースとなる概念です。
「Landing Zones」というAWSサービスそのものは存在しないようです。

Landing Zone | AWS Solutions
https://aws.amazon.com/jp/solutions/aws-landing-zone/

# おわりに
ここまで、CloudFormation StackSet及び関連AWSサービスについて見てきました。
次稿では、StackSetを利用して実際に必要なIAM Roleを全AWSアカウントに作成する作業について記述していきます。

# 参考URL
[AWS におけるマルチアカウント管理の手法とベストプラクティス](https://d0.awsstatic.com/events/jp/2017/summit/slide/D4T2-2.pdf)
[15分で教えるAWSの複数アカウント管理 - Qiita](https://qiita.com/14kw/items/46a0054d90a4f5d779c4)