CloudFormation StackSets で作れるStack instances上限回避のための垂直・水平分割

**2019/09/26更新：**
上限値が一定の値まで引き上げられただけだと思っていたんですが勘違いでした。
デフォルトの上限値が上がったのは確かなのですが、 `申請によりさらに最大値を上げること` ができるようにもなってました。

![cloudformation_service_quota.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/289ea9fd-c73e-d574-74e1-c81342a8aea3.png)

なので以下書いていることは、最大値を上げられなかった場合の話となります。
申請すれば普通に上げられるはずなので、もう起きないだろう状況ですね。。

----

初期設定やセキュリティの対応で全アカウント全リージョンに設定を入れたいときとかあると思います。
そのようなときは CloudFormation StackSets を使うのが便利なのですが制限が結構問題となります。

## CloudFormation StackSets の制限

- [AWS CloudFormation で StackSets の引き上げられた上限をサポート開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/08/aws-cloudformation-now-supports-higher-stacksets-limits/)
- [AWS CloudFormation Limits \- AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)

日本語のドキュメントは古い値のままなので英語のほうを見ましょう

### 100 stack sets per account

- StackSets
  - Maximum number of AWS CloudFormation stack sets you can create in your administrator account.
  - `20 -> 100` stack sets per account

StackSets の上限が 100 に増えたことで、ベストプラクティスに書いてあることが守りやすくなり、ライフサイクルや目的が異なるものを 1 つの StackSets に無理矢理入れ込む必要が少なくなりました。

> To get more granular control over updating individual stacks within your stack set, plan to create multiple stack sets.

それでも 100 は多いとは言えないので細分化しすぎも注意が必要です。

### 2000 stack instances per stack set

- Stack instances
  - Maximum number of stack instances you can create per stack set.
  - `500 -> 2000` stack instances per stack set

1 つの StackSet で作成できる Stack instances が 2000 に増えたことでデプロイ対象の幅が広がりました。

## Organization 内にある全アカウントの全リージョンに対してリソースを作りたい

Stack instance はデプロイする `アカウント × リージョン` の数だけ作成されます。

- アカウント数: 200
- リージョン数: 20

上記のような数のアカウントとリージョンを対象にすると `4000` Stack instaces が作成され、余裕で上限を超えます。

![CFnStackSetsSingleStackSet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/73819ae2-9c2b-b650-ad9b-5d3c2d067c4d.png)

### 垂直分割

リージョンごとに StackSet を作って回避する方法。
これなら `2000` アカウントまで対応できます。

![CFnStackSetsVerticalDivision.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/34112f94-8c3f-5e23-306e-e59c5f348274.png)

しかし StackSets がリージョン数分消費するため、仮に 10 個の StackSet を 20 リージョン に作ったら、1 アカウントあたり 200 StackSets の上限に達します。
StackSet の細分化には気を使う必要があります。

### 水平分割

アカウント ID の頭の数字ごとに StackSets を分けて回避する方法。

![CFnStackSets Horizontal Division.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135041/b9de1c27-383d-0653-280c-395bfffcfe0c.png)

アカウント ID はランダムで振られるため偏る可能性があります。
綺麗に割り振られた場合、 １ StackSet あたり 100 アカウント まで対応できます。
全体だと `1000` アカウント まで対応可能です。

## 余談：Control Tower の Guardrails

Control Tower の Guarlrails も CloudFormation StackSets を使っているので同じ問題を抱えているのでは？

Control Tower が対応しているのが現在 `4リージョン` なので、
1つのOUに配置できる アカウントは `500` が上限になります。
（GuardrailはOUを対象にして当てる） 

全アカウントに対して Guardrail を当てるには Organization 直下に OU を作る構造になりますが、Control Towerはデフォルトで直下に `Core` `Custom` という OU を作るため、全アカウントに対してなにかを行うというのは考えてないのかもしれない。

全アカウントに対してではなく OU に対してならば 500 の上限は妥当性がある気もしますね。

## 結局どうするのがいいのか

SCP で利用できる `リージョンを縛ってからの垂直分割` が個人的にはいいなと思ってます。

ただこれの問題があり Lambda@Edge を使っていると、アクセスがあった CloudFront のエッジのリージョンで実行されるため、リージョンを縛りにくいという点。悩ましい。

次点で Control Tower のように `役割ごとに水平分割して OU に分ける` 方法でしょうか。
こっちはどの単位で分けるのが最適なのか考えなければならないですね。