CloudFormationの超詳細解説 4/4 Stack編

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://zenn.dev/tech4anyone/articles/c05ee9777c6de0)。

この記事ではCloudFomationのStackに関連する内容を超詳細にまとめています。

具体的には以下流れで説明します。

- Stackとは
- Stackの仕組み
- Stackのセキュリティ
- Stack for Advance

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- CloudFormationがどういうサービスか説明できるようになりたい人
- CloudFormationを採用するときのベストプラクティスを説明できるようになりたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# Stackとは
CloudFormationテンプレートで管理されているリソースのかたまりをStackといいます。
1つのテンプレートにつき1つのStackが必ず生成されます。

そして、StackSetsはこのStackをマルチアカウントあるいはマルチリージョンで展開する仕組みを指します。

![](https://storage.googleapis.com/zenn-user-upload/3241db56f421-20231114.png)

StackSetsはStackの集まりと考えることができるので、ここからはStackSetsについてを解説していきます。

# StackSetsの仕組み
## 操作
StackSetsはStackをマルチアカウントあるいはマルチリージョンで展開する仕組みです。
StackSetsを作成する管理用のアカウントとリージョンを1つ決め、そこでCloudFormationを通常通り実行します。

すると、指定したリージョンとアカウントにStackインスタンスが作成され親のStackSetsは各Stackインスタンスを通して各対象アカウントあるいは対象リージョンにCloudFormationのCreateやUpdateを実行します。

操作としてはStackSetsのCreate、Update、Deleteが可能です。

なおｍStackSetsのUpdateを実施するとStackSetsで管理されているすべてのStackインスタンスでUpdateが走るため、環境選択を行うことができないので注意しましょう。
ただし、DeleteはStack単位で可能です。

## デプロイメントオプション
StackSetsをデプロイするときにはデプロイ順や同時実行数についてオプションで制御することが可能です。
| オプション名 | 説明 |
|--- | ---|
| Deployment Order | スタックが配置されるリージョンの順番を制御|
| Maximum Concurrent Accounts | 一度にスタックを展開できるリージョンごとのターゲットアカウントの最大数または割合を制御 |
| Region Concurrency | リージョンに展開されるスタックセットが直列か並列かを制御 |
| Failure Tolerance | いくつのリージョンでStack操作が失敗したらStackSets全体を失敗とするかを制御 |
| Retain Stacks | StackSetsからStackを削除したときにStackを保持するかどうかを制御 |

展開先が多い場合には同時実行数をあげて並列で処理することがおすすめです。
ただし、明示的に展開順を制御したい場合には直列にする必要があるので、要件によって使い分けるとよいでしょう。

## クロススタック参照
クロススタック参照とはCloudFormationテンプレートの値を別のCloudFormationテンプレートから参照することです。
具体的には、あるCloudFormationテンプレートのOutputsでExportした値をFn::ImportValueで参照することです。

実プロジェクトでは1種類のリソースを多数作るため、テンプレートを複数に分割する必要が出てきます。
例えばVPC・Subnet用のテンプレート、EC2用のテンプレート、RDS用のテンプレート、と分割します。

このように分割したときにEC2インスタンスやRDSインスタンスを起動するNW設定のために、VPC・Subnet用のテンプレートで作ったリソースのIDをEC2用やRDS用のテンプレートから参照する必要が出てきます。

こういった場面で使うのがクロススタック参照です。
参照したい値をOutputsのExportで出力し、利用したい側のテンプレートでFn::ImportValue/!ImportValueを使って入力します。

ただし、すべての参照も削除されない限り、基礎となるスタックを削除することはできない点に注意してください。
テンプレートAとテンプレートBで相互に参照しあうとこの罠にはまります。
テンプレートを分割する際には参照が一方向だけになるよう意識しましょう。

## ネストスタック
ネストスタックとはあるスタックから別のスタックを丸ごと呼び出す仕組みのことです。
クロススタック参照では、特定のパラメータのみをスタック間で参照していましたがネストスタックではスタックからスタックを丸ごと読み込みます。

![](https://storage.googleapis.com/zenn-user-upload/62ac664d584f-20231114.png)

AWSのベストプラクティスはネストスタックを活用し、可能な限りテンプレートの再利用を行うことです。
ネストされる側をパーツとして作り、環境全体はルートで定義することによってパーツ部分は汎化され、再利用可能になるからです。

ただし、Javaのアプリケーションなどと同様、どの程度までネストさせるかと管理のしやすさはある程度二者択一です。
この塩梅はプロジェクトで利用するリソースの量にもよるので、各プロジェクトごとに探っていく必要があります。

個人の経験から言うと、OSI参照モデルを参考にNW、IaaS、PaaS、SaaSという階層ごとかつEC2やRDSというサービスごとのメッシュで考えると比較的管理しやすいネストスタックになります。

# StackSetsのセキュリティ
StackSetsの実行権限制御はセルフマネージド型とサービスマネージド型があります。
セルフマネージド型はIAMロールを各アカウントに作る形です。
一方、サービスマネージド型はOrganization機能を利用します。

ここからそれぞれについて説明します。

## セルフマネージド型
まずはセルフマネージド型です。
このパターンはすでに述べたように各アカウントにIAMロールを作成し、クロスアカウントでCloudFormationを実行できる権限構成とします。

![](https://storage.googleapis.com/zenn-user-upload/436e71ca3a31-20231114.png)

## サービスマネージド型
次にサービスマネージド型です。
このパターンは対象のAWSアカウントがOrganizationで管理されていることがまず前提です。

![](https://storage.googleapis.com/zenn-user-upload/40b4251ca04f-20231114.png)

このパターンを利用するメリットは将来Organizationに新しいAWSアカウントが追加されたとき、自動でStackインスタンスがデプロイされます。

そのため、最低限守るべきセキュリティや監査の要件を満たすために使われることが多いです。

# StackSets for Advance
## Organizationとの統合
サービスマネージド型で実行権限を管理するときにはOrganization内のアカウントを一括で管理したいという要件があると思います。

ここではOrganizationと統合した場合に使える機能を簡単に説明します。

StackSetsをOrganizationと統合するとOrganizationに新しいAWSアカウントが追加されたときにStackインスタンスを自動的にデプロイする機能があります。

また、AWSのメンバーアカウントにStackSetsの管理を委任することも可能です。
前提として、Organizationとの信頼されたアクセスを有効にする必要がありますが委任された管理者はOrganizationが管理するアカウントにStackインスタンスをデプロイできるようになります。

# まとめ
この記事ではCloudFomationの実行に関連する内容を超詳細にまとめました。

- Stackとは
- Stackの仕組み
- Stackのセキュリティ
- Stack for Advance

次回はAWS Service Catalogを超詳細解説します。