こんにちは、SREチームの成田です。
今回もCDKネタで、CDKでNestedStackを使用した際にcdk diff
で差分が確認できないという問題に対してのハックを紹介します。
CDKについてはこちらの記事にて紹介してますので、よろしければご覧ください。 techblog.kiramex.com
NestedStackについて
NestedStackは名前の通りスタックを入れ子にして定義出来るCloudFormationの機能です。 こちらのイメージのようにスタックを階層的に定義することができます。
ネストされたスタックの操作 - AWS CloudFormation
CDKでNestedStackを使用する場合は、class NestedStack
を使用して子スタックを定義すると、親スタックで参照出来るようになります。
CDKでNestedStackを使用する際の問題点
CDKでNestedStackを使用したスタックを作成すると、cdk diff
での差分確認で、親スタックの差分は確認できますが子スタックの差分は確認することができません。
こちらのイメージでは、子スタックでECSを更新していますが、差分表示では親スタックのCloudFormationの差分(子スタックのCloudFormationテンプレートの更新)のみしか出てきません。
この問題に対してCDKでissueが上がっているものの、どうやら対応される見込みはなさそうです。
CloudFormation ChangeSetでNestedStackの差分確認
そこで、cdk diff
で差分を確認するのではなく、CloudFormationのChangeSetを使用して子スタックの差分確認をしてみます。
ChangeSetはスタックの更新前に変更箇所の確認をすることが出来るCloudFormationの機能です。 下記のイメージのように、更新の実行前にChangeSetを作成して変更箇所を確認することで安心してスタックの更新が行なえます。
まずはCDKでCloudFormationテンプレートを出力し、ChangeSetを作成します。
cdk deploy
で--no-execute
をつけて実行すると、ChangeSetの作成のみが行われ実行はされません。
$ npx cdk synth
$ npx cdk deploy --no-execute
これで作成されたルートスタックのChangeSetには子スタックの差分は含まれない(子スタックのCloudFormationテンプレートの更新のみ表示される)ので、このChangeSetをベースに子スタックの差分を含むChangeSetを手動で作成します。
CloudFormationのコンソール画面で、ルートスタックのスタックアクションから、既存スタックの変更セットを作成
を実行します。
指定するテンプレートは、CDK作業ディレクトリのcdk.out/
に出力されている親スタックのテンプレートをアップロードして使用します。
CDKで作成したChangeSetを参考にパラメータを設定します。
最後に、ネストされたスタックの変更セット
が有効になっていることを確認し、ChangeSetを作成します。
こうして作成したChangeSetでは子スタックのChangeSetも同時に作成され、子スタックでの変更内容も確認することができます。
注意点
ChangeSetの実行はCDKで作成されたChangeSetで行う
手動で作成したChangeSetはあくまで差分確認用です。 差分確認が済んだら手動で作成したChangeSetを削除し、変更の適応はCDKで作成したChangeSetを実行するのが安全です。
そもそもNestedStackのChangeSetには不具合がありそう
子スタック間、または子スタックと孫スタック間での参照の際に変更箇所が不適切に検出されたり、ChangeSetの作成に失敗する模様です。(下記issue参照) ただ、親子スタック間での参照であれば大丈夫そうな感じでした。
最後に
cdk diff
で表示される差分は、ローカルで作成したルートスタックのテンプレート差分のみしか表示されないので、子スタックの差分が表示されません。
そこで、CloudFormationのChangeSetを使用して子スタックの差分を確認するというアプローチを行いました。
ちなみに、ChangeSet作成に使用されるAPIの、CreateChangeSetでIncludeNestedStacksパラメータがTrueの場合(デフォルトはFalse)子スタックを含めた差分表示が行われます。
cdk deploy --no-execute
で実行されるCreateChangeSetではこのパラメータがFalseのため子スタックの差分が表示されず、再度コンソール画面から手動で作成する際にネストされたスタックの変更セット
を有効にすることでこのパラメータをTrueでCreateChangeSetを実行できるので、子スタックの差分が表示されるようになったわけです。
このように少し癖のあるNestedStackですが、スタックの分割に便利な機能なのでうまく使いこなしていきたいですね。