CDK における Stage の用法について、雑感を雑に書く

CDK Chatting #6 でいただいた質問に対する回答として雑感を書いてみた。
Docs

元ネタは、
CDK Chatting #6 より。
同じスタックを環境毎に使いまわしたい場合、bin/app.tsで静的/動的に複数作ったり分岐したりするよく見るパターンか、CDKのStageを活用するパターンがありそうですが、どのようなケースで使い分けると良いのでしょうか?また、CDKのStageを活用した実装で困った事はありますか?逆もあれば是非聞きたいです。
ちなみに私は Stage は本番で使ってないので、多分に想像・妄想の類が入った見解になります(おことわり)

後藤さんの回答。

まず、第一感として私が思っているのは Serverless Framework における stage の用法に比較的近いもの。
CDK 的にはポピュラーと思われる -c stage=xxx
による方法の別解、という感じで見ている節がある。
ちなみに Serverless Framework の stage と CDK の Stage はたまたま同じような「デプロイ環境ごとに Stack 作れる」という使い方ができるだけであって、実体としては全くの別物、という認識。
あくまで「同一のテンプレート定義をベースにしつつデプロイ環境ごとに Stack 作れる」を達成できる手段としての認識であって、その時利用する機能の名前がたまたま被ってる、というくらい。

公式情報に記載のある基本思想からおさらい。
An AWS Cloud Development Kit (AWS CDK) stage は、一緒にデプロイするように設定された 1 つ以上の CDK スタックのグループを表します。ステージを使用し、開発、テスト、本番稼働などの複数の環境にスタックの同じグループをデプロイします。
cdk synth を実行するとき、cdk.out に 2 つのクラウドアセンブリが作成されます。これらの 2 つのクラウドアセンブリには、各ステージの合成された AWS CloudFormation テンプレートとアセットが含まれています。次の内容は、プロジェクトディレクトリのスニペットです。 ...
一緒にデプロイして嬉しいひとかたまりがあれば、という話と解釈できる。
そういうのってなんだろう?と考えると、例えば依存する(あるいはしない)2個の Stack は意味的には実質ワンセット、みたいな場合だと思う。
Stage クラス自体は単体で大した機能をもっていないので、そういう側面を見ても Stage は特定の機能というよりはただの論理的な「箱」である、と解釈するのが自然ではないかと私は考えている。
後から入った開発者が間違って個別デプロイしないようにしたい、みたいな話を防ぐために Stage を被せて、複数個の Stack をまとめるのはアリだと思う。つまり、CDK App としての、開発者が意図する使われ方(like a インタフェース)を使い手=デプロイしたい人に強制できるようになる、ということ

視聴者の方から良い指摘をいただきました。このようなケースはまさしく複数個の Stack が論理的にはワンセットである好例ですね、と CDK Chatting ではお話ししていました

cdk synth を実行するとき、cdk.out に 2 つのクラウドアセンブリが作成されます。
各 Stage が同時に synth される、という性質も活用しどころな気がする。
つまり、デプロイ環境ごとに異なるモノを構築する場合に、各環境の synth が壊れないことを確認したいケースが向いているのではないか。
例えば、環境ごとに同一の Stack を使いまわしている場合において、本番環境だけ適用する Aspect があるとかで、他の環境とはリソース差分がある、のようなケース。
こういう場合、prod でしか発覚しない、意図しない実装のミスが混入してしまったときに(Stage を使う設計なら、環境ごとに個別 synth する実装よりも)不具合の発覚が早まるので嬉しい。
dev/prod 専属の WAF ルール入れてます、とか、Prod と QA にはそれぞれ S3 レプリケーションの src/dst 構成を入れている、とか。

あとは、React の Context みたいな用法ができるかも?というのは考えた。
ステージを継承した独自クラスに設定値引っ張るためのインタフェースを定義しておいて、Stack からそれを(あるいは Stage name を)引っ張ることで Feature Flag のような振る舞いを Construct tree 間の Props バケツリレーをせずに参照できるようにする、、、、的な。
ただしこれは妄想の域を出ない。し、これは Context の引数でも同じことができるのでそこまで実用的なじゃない気もする。