見出し画像

CDK でネストスタック構築時に、変更点を確認する手順

こんにちは、build サービスチームで DevOps をやっている t.g. です。
今日は、CDK で作ったネストスタックを更新する際に、変更点をわかりやすく確認する手順をまとめました。
aws コマンドや sam コマンドを使う場合は知っていましたが、cdk コマンドを使うやり方は案外手こずりました。



予備知識: ネストスタックとは

あるスタックからそのリソースとして、別のスタックを作成する仕組み
親スタックからそのリソースとして、子スタックを作成することができるので、テンプレートをパーツとして再利用することができます。

詳細は、AWS ドキュメントのネストされたスタックの操作 を参照


実験

前提

以下のような親子関係を持つネストスタックを CDK で構築。
リソースの追加と変更を行うと仮定して、その変更点がどれだけ見られるか確認します

Try1 - cdk diff で確認

まずは、cdk 付属のコマンド cdk diff で実施。

$ cdk diff

    (snip)
Resources
[~] AWS::CloudFormation::Stack ChildStackNo1.NestedStack/ChildStackNo1.NestedStackResource ChildStackNo1NestedStackChildStackNo1NestedStackResourceDCD0A30A 
 ├─ [~] NestedTemplate
 │   └─ [~] .Resources:
 │       ├─ [~] .CDKMetadata:
 │       ├─ [+] Added: .Queue4A7E3555
 │       └─ [~] .TableCD117FA1:
 │           └─ [~] .Properties:
 │               └─ [~] .TableName:
 │                   ├─ [-] test-table
 │                   └─ [+] test-table2
     (snip)

ポイント

  • DynamoDB Table はリプレースされるのに、ここからは直接読み取れない

  • Queue らしきものが追加されるのはわかるが、ロジカル名で出されてもわからない。リソース種別もほしいところ


Try2 - cdk コマンドで変更セットを作成

次は、cdk コマンドで変更セット(changeset) のみを作成し、デプロイを行わない設定で実施します

cdk deploy --no-execute

そして、作成された変更セットを aws コマンドで確認します。

$ aws cloudformation describe-change-set --change-set-name ${changesetArn}

    (snip)

{
    "Changes": [
        {
            "Type": "Resource",
            "ResourceChange": {
                "Action": "Modify",
                "LogicalResourceId": "ChildStackNo1NestedStackChildStackNo1NestedStackResourceDCD0A30A",
                "PhysicalResourceId": "arn:aws:cloudformation:us-west-2:xxxxxxxxxx:stack/ParentStack-ChildStackNo1NestedStackChildStackNo1Nest",
                "ResourceType": "AWS::CloudFormation::Stack",
                "Replacement": "False",
                "Scope": [
                    "Properties"
                ],
                "Details": [
                    {
                        "Target": {
                            "Attribute": "Properties",
                            "Name": "TemplateURL",
                            "RequiresRecreation": "Never"
                        },
                        "Evaluation": "Static",
                        "ChangeSource": "DirectModification"
                    }
                ]
            }
        }
    ],
    "ChangeSetName": "cdk-deploy-change-set",
    
    (snip)

どの子スタックが変更されるかが表示されるだけで、リソースレベルの変更点は表示されず。
下記のように、CloudFormation コンソールも同様でした(親/子スタックともに確認できず)

CloudFormation コンソールから確認
LogicalID の下に子スタックへの 変更セットがあれば完璧なのに・・


Try3 - aws コマンドで変更セットを作成

どうやらcdk deploy --no-execute には、ネストスタックの情報を含めるオプション(--include-nested-stacks) が含まれてない模様です。
なので、変更セットの作成は aws コマンドで実施してみることに。

cdk コマンドとの兼ね合いもあるので、以下のような手順を行いました

  1. `cdk deploy --no-execute`
    各テンプレート、アセット(あれば)の S3 アップロードをやってもらいます。変更セットが作られますが無視

  2. `./cdk.out` フォルダ内の parent テンプレートを CDK 用 S3 へ手作業アップロード
    Note: step1 でアップロード済みですが、ファイル名類推が面倒ですし、こっちの方が早いので手でアップロード
    Note: `./cdk.out/manifest.json` からファイル名が確認できます

  3. aws コマンドで変更セットを作成
    下記参照

  4. 変更セットをCLIから確認
    DynamoDB がリプレースされることや、追加リソースの種類が確認できました。下記参照

  5. CFn コンソールからも確認
    こちらも、DynamoDB がリプレースされることや、追加リソースの種類が確認できました。下記参照

  6. (重要) この変更セットは使わないので削除

  7. (重要) `cdk deploy` でデプロイ適用

# 3. aws コマンドで変更セットを作成
aws cloudfomation create-change-set \
  --include-nested-stacks \
  --stack-name ${STACK_NAME} \
  --change-set-name ${CHANGE_SET_NAME} \
  --template-url ${TEMPLATE_URL_IN_HTTPS_FORM}

# 4. 変更セットをCLIから確認
aws cloudformation describe-change-set --change-set-name ${changesetArn}
{
    "Changes": [
        {
            "Type": "Resource",
            "ResourceChange": {
                "Action": "Add",
                "LogicalResourceId": "Queue4A7E3555",
                "ResourceType": "AWS::SQS::Queue",
                "Scope": [],
                "Details": []
            }
        },
        {
            "Type": "Resource",
            "ResourceChange": {
                "Action": "Modify",
                "LogicalResourceId": "TableCD117FA1",
                "PhysicalResourceId": "test-table",
                "ResourceType": "AWS::DynamoDB::Table",
                "Replacement": "True",
                "Scope": [
                    "Properties"
                ],
                "Details": [
                    {
                        "Target": {
                            "Attribute": "Properties",
                            "Name": "TableName",
                            "RequiresRecreation": "Always"
                        },
                        "Evaluation": "Static",
                        "ChangeSource": "DirectModification"
                    }
                ]
            }
        }
    ],
      (snip)

# 6. 変更セットは削除
aws cloudformation delete-change-set \
  --stack-name ${STACK_NAME} \
  --change-set-name ${CHANGE_SET_NAME}
CFn コンソールから、親スタックの変更セットを確認
子スタックへのリンクが貼られています
CFn コンソールから、子スタックの変更セットを確認
追加リソースの種別や、変更リソースのリプレースが確認できます

Note: 上記のやりかたをパイプラインで組んで、CFn コンソールへのリンクを Slack で流すと見やすそうです。確認するなら CLI よりも GUI の方が良いですね


おまけ - cdk コマンドに include-nested-stacks オプション追加

現在(7/12) 、cdk コマンド作成の変更セットにネストスタックが含まれるように作られています。近いうちに実装されそうな予感
Add IncludeNestedStacks option to createChangeSet



まとめ

aws コマンドを組み合わせれば、cdk で作成したネストスタックの変更ポイントも満足できるレベルで確認ができました。
CICD などで実際にデプロイする前に、変更点を確認・承認をすることがあるのでそこで使いたいと思っています

cdk コマンドにも同様の機能が実装されれば、cdk コマンド単体で変更セット作成ができるようになるはずです

みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!