はじめに
CDK for Terraform (CDKTF)で multi-stack にすることはよくあると思います。dev, staging, prod とスタックを3つ用意したり、リリースの単位でスタックを分けたり。
私も最近 CDK for Terraform を使っており、スタックをどのように分割するか考えていました。公式ドキュメントを読んだり、実際に使ってみた結果、考えがまとまったので、記事にします。
スタックをどのように分けるか
dev, staging, prod のように、環境ごとにスタックを分けている人は多いと思います。この場合、ベースのスタックは同じで、環境変数(パラメータ)だけ変更するのが一般的だと思います。
他にも、
- マイクロサービスごとにスタックを分ける
- 同じサービス内で、アプリケーション部分とオペレーション部分で分ける(ログの保存/検索の部分だけ分ける等)
などが考えられます。
スタックを分けることで、デプロイ時の影響範囲を限定したり、更新頻度が高い部分を分離して更新の衝突を避けたりできます。
CDKTF のドキュメントの Best practice にも、スタックの分割については触れられています(参考になるかは微妙な印象ですが...)
複数のスタックをまとめてデプロイしたい場合
このように必要に応じてスタックを分けますが、デプロイ時に、スタック単体でデプロイしたい場合もあれば、複数のスタックをまとめてデプロイしたい場合もあります。
「影響を狭めるために、今回はモニタリングの部分だけ更新したい」「新規の環境構築なので、全部まとめてデプロイしたい」といった場合です。
AWS CDK のようにスタックを入れ子に(入れ子 = 英語だと nest)できれば、この要求に対応しやすいですが *1、 CDKTF は、スタックを入れ子にできません。
そこで、スタックを分けつつ、必要な場合は複数のスタックを指定してデプロイコマンドを叩くことになります。
複数のスタックをデプロイしたい場合、deploy コマンドで複数のスタックをスペース区切りで指定するか
cdktf deploy app1-dev app2-dev
ワイルドカードで指定するかのどちらかになります。
cdktf deploy "*-dev"
スタックが多いと個別で指定するのが大変なため、ワイルドカードをうまく使えるようにスタックIDを命名していくことが重要になります。
ワイルドカードでのデプロイの注意点
上手にスタックIDを命名することで、ワイルドカードを使ってデプロイできることがわかりましたが、いくつか注意点があります。
複数スタックのデプロイ時には --parallelism コマンドを利用する
cdktf deploy
コマンドを実行すると、diff が表示された後、デプロイを実行するかどうか尋ねられます。しかし、複数のスタックのデプロイが並列に行われるので、普通に実行すると diff が非常に見づらくなります。
--parallelism 1
をすると、同時に1つのデプロイしか実行されなくなるため、diff が見づらくなることはありません。
cdktf deploy `*-dev` --parallelism 1
diff を確認しなくていいので並列で高速にデプロイしたい場合は、 --auto-approve
をつければ、OKです。この場合、コマンドを実行後、確認無くデプロイされるので注意してください。CI でデプロイする場合はこちらを使うことになるかと思います。
cdktf deploy `*-dev` --auto-approve
cdktf diff コマンドは multi-stack に対応していない
diff コマンドは、マルチスタックに対応していないので注意してください。diff は基本的に cdktf deploy
で確認するこになります。
# NG cdktf diff `*-dev` # app1-dev の diff しか見られない cdktf diff app1-dev app2-dev
その他ベストプラクティスについて
CDK for Terraform は、通常の Terraform のラッパーではありますが、 Terraform と違って if による分岐や、関数(コンストラクタ)の引数によるパラメータの受け渡しなど言語の機能が利用でき、表現力が変わってきます。よって、既存の Terraform の考えに縛られずに設計していくことが重要になります。
例えば、本来 Terraform では workspace と tfvars を使ってパラメータを管理していましたが、CDK for Terraform ではコンストラクタの引数でそれが可能になっており、 Terraform の tfvars の機能を使う必要がありません。
この場合は基本的に言語の機能を利用するほうが、メンテナンスしやすい設計になると思います。
まとめ
- スタックがデプロイの最小単位なので、それを意識してスタック構成を考える
- スタックのデプロイにはワイルドカードが使えるので、その前提でスタックのIDをつける
- ワイルドカードをデプロイするときは
--parallelism
オプションを使うのが良い
この記事に有料部分はありませんが、もし役に立って、お金を払ってもいいと思ったかたは購入をお願いします。
*1:一方で、スタックの管理が複雑になるという欠点もあります