[AWS CDK] `cdk deploy` で変更セットの使用をスキップして、スタックデプロイを高速化してみた

検証ではデプロイ時間を約40%短縮できました。ただし使い所は選ぶようです。
2023.06.11

こんにちは、CX事業本部 Delivery部の若槻です。

昨年9月に AWS CDK で次のような機能アップデートがありました。

Features

- cli: cdk deploy --method=direct is faster (#22079) (dd6ead4)

CDK スタックのデプロイコマンド実行で --method=direct パラメーターを使うことにより、変更セット(ChangeSet)の使用をスキップして直接デプロイできるという機能です。

CDK ではデプロイ処理の一部として AWS CloudFormation の 変更セットが既定で使用されます。スタックの変更セットを事前に作成することにより、デプロイによって実行中のリソースにどのような影響があるか確認することができますが、CDK のデプロイ処理内では変更セットの作成から実行まで自動で行われ、そもそもユーザーが影響の確認を行うことはできないため、変更セットの使用をスキップしてしまいデプロイ処理の高速化を図ろうというものです。

今回は、--method=direct パラメーターを使うことで cdk deploy がどれくらい早くなるのか試してみました。

試してみた

次のような、10個のスタックにパラメーターストアを10個ずつ、計100個作成した CDK App を予め作っておきます。

bin/cdk_sample_app.ts

import { aws_ssm, Stack, StackProps, App } from 'aws-cdk-lib';
import { Construct } from 'constructs';

class MyStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // スタックごとに10個のパラメーターストアを作成
    for (let i = 1; i <= 10; i++) {
      for (let j = 1; j <= 10; j++) {
        new aws_ssm.StringParameter(this, `testParameter${i}-${j}`, {
          stringValue: 'initial deploy',
        });
      }
    }
  }
}

const app = new App();

// スタックを10個作成
for (let i = 1; i <= 10; i++) {
  new MyStack(app, `testStack${i}`);
}

これら全てのパラメーターストアの値(stringValue)を変更した時の cdk deploy の所要時間を計測してみます。

変更セットを使用した場合

まずは、通常の cdk deploy で変更セットを使用した場合のデプロイ所要時間を計測してみます。

作成済みの100個すべてのパラメーターストアのパラメーター値を変更するデプロイを行います。

bin/cdk_sample_app.ts

        new aws_ssm.StringParameter(this, `testParameter${i}-${j}`, {
-          stringValue: 'initial deploy',
+          stringValue: 'deploy with change set',
        });

パラメーターを指定せずに cdk deploy を実行します。

cdk deploy --all

すると変更セットを使用したデプロイが行われます。変更セットを使用した場合は、デプロイ中にコンソール上にプログレスバーが表示されます。

しばらく待つと全てのパラメーターストアのデプロイが完了しました。

コマンド実行後の画面出力(長いので折り畳んでいます)
cdk deploy --all                

  Synthesis time: 3.18s

testStack1:  start: Building 920af5082f6a342871256e0103387b2951c64e66466ab089489c136d73e471bc:current_account-current_region
testStack1:  success: Built 920af5082f6a342871256e0103387b2951c64e66466ab089489c136d73e471bc:current_account-current_region
testStack2:  start: Building 9b6efc85dba769ca77c4b8e1d3ca74e4977150f54b932fe256cd1f8705482eef:current_account-current_region
testStack2:  success: Built 9b6efc85dba769ca77c4b8e1d3ca74e4977150f54b932fe256cd1f8705482eef:current_account-current_region
testStack1:  start: Publishing 920af5082f6a342871256e0103387b2951c64e66466ab089489c136d73e471bc:current_account-current_region
testStack2:  start: Publishing 9b6efc85dba769ca77c4b8e1d3ca74e4977150f54b932fe256cd1f8705482eef:current_account-current_region
testStack3:  start: Building 90fc731eb7819142ffb94779b6af50fb5f18107a63cfce6a6367489373294837:current_account-current_region
testStack3:  success: Built 90fc731eb7819142ffb94779b6af50fb5f18107a63cfce6a6367489373294837:current_account-current_region
testStack3:  start: Publishing 90fc731eb7819142ffb94779b6af50fb5f18107a63cfce6a6367489373294837:current_account-current_region
testStack4:  start: Building ed5551c541db6df883662643f0c03d19c94253284a8f433e6f3c9be66ab62e53:current_account-current_region
testStack4:  success: Built ed5551c541db6df883662643f0c03d19c94253284a8f433e6f3c9be66ab62e53:current_account-current_region
testStack5:  start: Building 7cf4cd298aa5715bf44eef4c74fc1de17e5d01a78a0e8ff6bcf69df82e32d711:current_account-current_region
testStack5:  success: Built 7cf4cd298aa5715bf44eef4c74fc1de17e5d01a78a0e8ff6bcf69df82e32d711:current_account-current_region
testStack4:  start: Publishing ed5551c541db6df883662643f0c03d19c94253284a8f433e6f3c9be66ab62e53:current_account-current_region
testStack6:  start: Building 182325dfc928393358a1ae120acef0ec330bca1db145f5ddf7170bf73cb13157:current_account-current_region
testStack6:  success: Built 182325dfc928393358a1ae120acef0ec330bca1db145f5ddf7170bf73cb13157:current_account-current_region
testStack5:  start: Publishing 7cf4cd298aa5715bf44eef4c74fc1de17e5d01a78a0e8ff6bcf69df82e32d711:current_account-current_region
testStack7:  start: Building aae9f2eae1299b5f23ea950ddf77460e63f71b4d7d816b813a8f3de170e878ac:current_account-current_region
testStack7:  success: Built aae9f2eae1299b5f23ea950ddf77460e63f71b4d7d816b813a8f3de170e878ac:current_account-current_region
testStack6:  start: Publishing 182325dfc928393358a1ae120acef0ec330bca1db145f5ddf7170bf73cb13157:current_account-current_region
testStack8:  start: Building dac32369c3df78aba4932e2593eae1e45a9b0b954291211e0acad6e5f1e50e3d:current_account-current_region
testStack8:  success: Built dac32369c3df78aba4932e2593eae1e45a9b0b954291211e0acad6e5f1e50e3d:current_account-current_region
testStack7:  start: Publishing aae9f2eae1299b5f23ea950ddf77460e63f71b4d7d816b813a8f3de170e878ac:current_account-current_region
testStack9:  start: Building 4f94e06fa400adaa619bdb35b69a4d141ccab77c90aab3ae09b857c7abcf3222:current_account-current_region
testStack9:  success: Built 4f94e06fa400adaa619bdb35b69a4d141ccab77c90aab3ae09b857c7abcf3222:current_account-current_region
testStack8:  start: Publishing dac32369c3df78aba4932e2593eae1e45a9b0b954291211e0acad6e5f1e50e3d:current_account-current_region
testStack10:  start: Building e0b46a66218017c6c401f44a72204d6733a4bc6c54e9be65656ca527736a533a:current_account-current_region
testStack10:  success: Built e0b46a66218017c6c401f44a72204d6733a4bc6c54e9be65656ca527736a533a:current_account-current_region
testStack3:  success: Published 90fc731eb7819142ffb94779b6af50fb5f18107a63cfce6a6367489373294837:current_account-current_region
testStack3
testStack9:  start: Publishing 4f94e06fa400adaa619bdb35b69a4d141ccab77c90aab3ae09b857c7abcf3222:current_account-current_region
testStack4:  success: Published ed5551c541db6df883662643f0c03d19c94253284a8f433e6f3c9be66ab62e53:current_account-current_region
testStack10:  start: Publishing e0b46a66218017c6c401f44a72204d6733a4bc6c54e9be65656ca527736a533a:current_account-current_region
testStack1:  success: Published 920af5082f6a342871256e0103387b2951c64e66466ab089489c136d73e471bc:current_account-current_region
testStack7:  success: Published aae9f2eae1299b5f23ea950ddf77460e63f71b4d7d816b813a8f3de170e878ac:current_account-current_region
testStack2:  success: Published 9b6efc85dba769ca77c4b8e1d3ca74e4977150f54b932fe256cd1f8705482eef:current_account-current_region
testStack8:  success: Published dac32369c3df78aba4932e2593eae1e45a9b0b954291211e0acad6e5f1e50e3d:current_account-current_region
testStack6:  success: Published 182325dfc928393358a1ae120acef0ec330bca1db145f5ddf7170bf73cb13157:current_account-current_region
testStack5:  success: Published 7cf4cd298aa5715bf44eef4c74fc1de17e5d01a78a0e8ff6bcf69df82e32d711:current_account-current_region
testStack3: deploying... [3/10]
testStack10:  success: Published e0b46a66218017c6c401f44a72204d6733a4bc6c54e9be65656ca527736a533a:current_account-current_region
testStack9:  success: Published 4f94e06fa400adaa619bdb35b69a4d141ccab77c90aab3ae09b857c7abcf3222:current_account-current_region
testStack3: creating CloudFormation changeset...

   testStack3

  Deployment time: 79.82s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack3/6a195790-0847-11ee-847f-0673bbff0e97

  Total time: 83s

testStack4
testStack4: deploying... [4/10]
testStack4: creating CloudFormation changeset...

   testStack4

  Deployment time: 79.44s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack4/5f596b60-0847-11ee-a1fd-0e38816352d1

  Total time: 82.62s

testStack1
testStack1: deploying... [1/10]
testStack1: creating CloudFormation changeset...

   testStack1

  Deployment time: 79.92s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack1/466553d0-0847-11ee-b41b-06024cc82509

  Total time: 83.09s

testStack7
testStack7: deploying... [7/10]
testStack7: creating CloudFormation changeset...

   testStack7

  Deployment time: 79.45s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack7/548ef7e0-0847-11ee-9d80-0a906fa54707

  Total time: 82.62s

testStack2
testStack2: deploying... [2/10]
testStack2: creating CloudFormation changeset...

   testStack2

  Deployment time: 84.52s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack2/7fcebee0-0847-11ee-aad4-0e7b3d737ad1

  Total time: 87.69s

testStack8
testStack8: deploying... [8/10]
testStack8: creating CloudFormation changeset...

   testStack8

  Deployment time: 79.72s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack8/74fc3510-0847-11ee-a3a7-0a3091a47f85

  Total time: 82.89s

testStack6
testStack6: deploying... [6/10]
testStack6: creating CloudFormation changeset...

   testStack6

  Deployment time: 79.68s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack6/987811d0-0847-11ee-abf2-0672535c7cbb

  Total time: 82.85s

testStack5
testStack5: deploying... [5/10]
testStack5: creating CloudFormation changeset...

   testStack5

  Deployment time: 80.12s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack5/8db71430-0847-11ee-b41b-06024cc82509

  Total time: 83.3s

testStack10
testStack10: deploying... [10/10]
testStack10: creating CloudFormation changeset...

   testStack10

  Deployment time: 84.73s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack10/a33f9f20-0847-11ee-b3a8-06a2287a034d

  Total time: 87.91s

testStack9
testStack9: deploying... [9/10]
testStack9: creating CloudFormation changeset...

   testStack9

  Deployment time: 79.58s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack9/b1205350-0847-11ee-b113-0a695461543b

  Total time: 82.76s

各スタックのデプロイメント時間は以下のようになりました。

Stack Name Deployment Time (s)
testStack1 79.92
testStack2 84.52
testStack3 79.82
testStack4 79.44
testStack5 80.12
testStack6 79.68
testStack7 79.45
testStack8 79.72
testStack9 79.58
testStack10 84.73
合計 806.98

合計で806.98秒(13分26秒)を要する結果となりました。

cdk deploy で 変更セット使用をスキップした場合

次に --method=direct パラメーターを使った場合です。

先程と同じく、作成済みの100個すべてのパラメーターストアのパラメーター値を変更するデプロイを行います。

bin/cdk_sample_app.ts

        new aws_ssm.StringParameter(this, `testParameter${i}-${j}`, {
-          stringValue: 'deploy with change set',
+          stringValue: 'deploy directly',
        });

パラメーターを指定せずに cdk deploy を実行します。

cdk deploy --all --method=direct

すると変更セットを使用せずにデプロイが行われます。変更セットを使用しない場合は、デプロイ中にコンソール上にプログレスバーが表示されなくなります。

しばらく待つと全てのパラメーターストアのデプロイが完了しました。

コマンド実行後の画面出力(長いので折り畳んでいます)
$ cdk deploy --all --method=direct

  Synthesis time: 2.98s

testStack1:  start: Building 2185fa04792a5c354e52ead714bc7002daa5da01ee79b2b9e81dd0acae4720c8:current_account-current_region
testStack1:  success: Built 2185fa04792a5c354e52ead714bc7002daa5da01ee79b2b9e81dd0acae4720c8:current_account-current_region
testStack2:  start: Building 18f5b063687b751952e37a3d591d68ece3cc27b8c22dd370ba7ff279f6593d04:current_account-current_region
testStack2:  success: Built 18f5b063687b751952e37a3d591d68ece3cc27b8c22dd370ba7ff279f6593d04:current_account-current_region
testStack1:  start: Publishing 2185fa04792a5c354e52ead714bc7002daa5da01ee79b2b9e81dd0acae4720c8:current_account-current_region
testStack2:  start: Publishing 18f5b063687b751952e37a3d591d68ece3cc27b8c22dd370ba7ff279f6593d04:current_account-current_region
testStack3:  start: Building 1ebe511a5d59d7bf2506b2e5f5663fc9f533f10705e3db0a16f12d7d12d50e5a:current_account-current_region
testStack3:  success: Built 1ebe511a5d59d7bf2506b2e5f5663fc9f533f10705e3db0a16f12d7d12d50e5a:current_account-current_region
testStack4:  start: Building 1bf20fca1b128818f6e27710d4ce03e892c3243a81e5a479e0f894253d408876:current_account-current_region
testStack4:  success: Built 1bf20fca1b128818f6e27710d4ce03e892c3243a81e5a479e0f894253d408876:current_account-current_region
testStack3:  start: Publishing 1ebe511a5d59d7bf2506b2e5f5663fc9f533f10705e3db0a16f12d7d12d50e5a:current_account-current_region
testStack5:  start: Building 937b9a09fd80b14cfa750d4dfe1750844f7de638919d314f35c79e5e36d302b9:current_account-current_region
testStack5:  success: Built 937b9a09fd80b14cfa750d4dfe1750844f7de638919d314f35c79e5e36d302b9:current_account-current_region
testStack4:  start: Publishing 1bf20fca1b128818f6e27710d4ce03e892c3243a81e5a479e0f894253d408876:current_account-current_region
testStack6:  start: Building 2d47b1eab33b44ea261cb2997f3e286324c9c688372fd7515dfef370fd92026e:current_account-current_region
testStack6:  success: Built 2d47b1eab33b44ea261cb2997f3e286324c9c688372fd7515dfef370fd92026e:current_account-current_region
testStack5:  start: Publishing 937b9a09fd80b14cfa750d4dfe1750844f7de638919d314f35c79e5e36d302b9:current_account-current_region
testStack6:  start: Publishing 2d47b1eab33b44ea261cb2997f3e286324c9c688372fd7515dfef370fd92026e:current_account-current_region
testStack7:  start: Building 07bf8982eb0c929c14567505214772584ddf4b93f518071c348ebc248e17620f:current_account-current_region
testStack7:  success: Built 07bf8982eb0c929c14567505214772584ddf4b93f518071c348ebc248e17620f:current_account-current_region
testStack8:  start: Building 577ce2c67eb694e04b156dff978a3d36848e48902ec1004247f3194a831e1d1e:current_account-current_region
testStack8:  success: Built 577ce2c67eb694e04b156dff978a3d36848e48902ec1004247f3194a831e1d1e:current_account-current_region
testStack7:  start: Publishing 07bf8982eb0c929c14567505214772584ddf4b93f518071c348ebc248e17620f:current_account-current_region
testStack9:  start: Building 093760cc665107e968492bdc8c9c4605659dc63a98da2d9e61d91997a14836e7:current_account-current_region
testStack9:  success: Built 093760cc665107e968492bdc8c9c4605659dc63a98da2d9e61d91997a14836e7:current_account-current_region
testStack8:  start: Publishing 577ce2c67eb694e04b156dff978a3d36848e48902ec1004247f3194a831e1d1e:current_account-current_region
testStack10:  start: Building 10be2f11cd50bde8358c30d7e7c18f06c801e8dcfbb695d543bae2ee1d263596:current_account-current_region
testStack10:  success: Built 10be2f11cd50bde8358c30d7e7c18f06c801e8dcfbb695d543bae2ee1d263596:current_account-current_region
testStack7:  success: Published 07bf8982eb0c929c14567505214772584ddf4b93f518071c348ebc248e17620f:current_account-current_region
testStack7
testStack9:  start: Publishing 093760cc665107e968492bdc8c9c4605659dc63a98da2d9e61d91997a14836e7:current_account-current_region
testStack1:  success: Published 2185fa04792a5c354e52ead714bc7002daa5da01ee79b2b9e81dd0acae4720c8:current_account-current_region
testStack10:  start: Publishing 10be2f11cd50bde8358c30d7e7c18f06c801e8dcfbb695d543bae2ee1d263596:current_account-current_region
testStack4:  success: Published 1bf20fca1b128818f6e27710d4ce03e892c3243a81e5a479e0f894253d408876:current_account-current_region
testStack3:  success: Published 1ebe511a5d59d7bf2506b2e5f5663fc9f533f10705e3db0a16f12d7d12d50e5a:current_account-current_region
testStack5:  success: Published 937b9a09fd80b14cfa750d4dfe1750844f7de638919d314f35c79e5e36d302b9:current_account-current_region
testStack8:  success: Published 577ce2c67eb694e04b156dff978a3d36848e48902ec1004247f3194a831e1d1e:current_account-current_region
testStack2:  success: Published 18f5b063687b751952e37a3d591d68ece3cc27b8c22dd370ba7ff279f6593d04:current_account-current_region
testStack6:  success: Published 2d47b1eab33b44ea261cb2997f3e286324c9c688372fd7515dfef370fd92026e:current_account-current_region
testStack7: deploying... [7/10]
testStack9:  success: Published 093760cc665107e968492bdc8c9c4605659dc63a98da2d9e61d91997a14836e7:current_account-current_region
testStack10:  success: Published 10be2f11cd50bde8358c30d7e7c18f06c801e8dcfbb695d543bae2ee1d263596:current_account-current_region
testStack7: updating stack...

   testStack7

  Deployment time: 48.06s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack7/548ef7e0-0847-11ee-9d80-0a906fa54707

  Total time: 51.04s

testStack1
testStack1: deploying... [1/10]
testStack1: updating stack...

   testStack1

  Deployment time: 47.71s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack1/466553d0-0847-11ee-b41b-06024cc82509

  Total time: 50.69s

testStack4
testStack4: deploying... [4/10]
testStack4: updating stack...

   testStack4

  Deployment time: 47.56s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack4/5f596b60-0847-11ee-a1fd-0e38816352d1

  Total time: 50.54s

testStack3
testStack3: deploying... [3/10]
testStack3: updating stack...

   testStack3

  Deployment time: 47.59s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack3/6a195790-0847-11ee-847f-0673bbff0e97

  Total time: 50.57s

testStack5
testStack5: deploying... [5/10]
testStack5: updating stack...

   testStack5

  Deployment time: 47.91s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack5/8db71430-0847-11ee-b41b-06024cc82509

  Total time: 50.89s

testStack8
testStack8: deploying... [8/10]
testStack8: updating stack...

   testStack8

  Deployment time: 47.82s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack8/74fc3510-0847-11ee-a3a7-0a3091a47f85

  Total time: 50.8s

testStack2
testStack2: deploying... [2/10]
testStack2: updating stack...

   testStack2

  Deployment time: 48.01s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack2/7fcebee0-0847-11ee-aad4-0e7b3d737ad1

  Total time: 50.99s

testStack6
testStack6: deploying... [6/10]
testStack6: updating stack...

   testStack6

  Deployment time: 47.68s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack6/987811d0-0847-11ee-abf2-0672535c7cbb

  Total time: 50.67s

testStack9
testStack9: deploying... [9/10]
testStack9: updating stack...

   testStack9

  Deployment time: 47.92s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack9/b1205350-0847-11ee-b113-0a695461543b

  Total time: 50.9s

testStack10
testStack10: deploying... [10/10]
testStack10: updating stack...

   testStack10

  Deployment time: 47.82s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/testStack10/a33f9f20-0847-11ee-b3a8-06a2287a034d

  Total time: 50.8s

各スタックのデプロイメント時間は以下のようになりました。

Stack Deployment Time (s)
testStack1 47.71
testStack2 48.01
testStack3 47.59
testStack4 47.56
testStack5 47.91
testStack6 47.68
testStack7 48.06
testStack8 47.82
testStack9 47.92
testStack10 47.82

合計で478.08秒(7分58秒)を要する結果となりました。変更セットを使用した場合と比べ、デプロイ時間を約40%短縮できています。

注意点

じゃあ今度から cdk deploy は CI/CD パイプラインでの自動デプロイ含めすべて --method=direct をつけて実行するようにすれば皆ハッピーなのでは?と思うかもしれませんが、注意点というか課題がありました。

デプロイ実行時に変更の無いスタックがある場合は次のように No updates are to be performed. というエラーが発生してしまうことです。変更スタックを使わずに直接デプロイする場合は cloudformation update-stack コマンドが使われているような挙動ですね。(こちらの記事にもある通り、冪等性が無いというやつです。)

$ cdk deploy --all --method=direct

  Synthesis time: 2.97s

testStack1
testStack1: deploying... [1/10]
testStack1: updating stack...

   testStack1 failed: Error [ValidationError]: No updates are to be performed.
    at Request.extractError (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:46232)
    at Request.callListeners (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:89224)
    at Request.emit (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:88672)
    at Request.emit (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:195101)
    at Request.transition (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:188653)
    at AcceptorStateMachine.runTo (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:153525)
    at /Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:153855
    at Request.<anonymous> (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:188945)
    at Request.<anonymous> (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:195176)
    at Request.callListeners (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:89392) {
  code: 'ValidationError',
  time: 2023-06-11T11:11:50.533Z,
  requestId: '8ba2f48a-2ebc-4454-a933-b07c1f9f97b0',
  statusCode: 400,
  retryable: false,
  retryDelay: 880.5633953781091
}

  Deployment failed: Error [ValidationError]: No updates are to be performed.
    at Request.extractError (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:46232)
    at Request.callListeners (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:89224)
    at Request.emit (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:88672)
    at Request.emit (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:195101)
    at Request.transition (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:188653)
    at AcceptorStateMachine.runTo (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:153525)
    at /Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:153855
    at Request.<anonymous> (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:188945)
    at Request.<anonymous> (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:195176)
    at Request.callListeners (/Users/wakatsuki.ryuta/.npm-global/lib/node_modules/aws-cdk/lib/index.js:298:89392) {
  code: 'ValidationError',
  time: 2023-06-11T11:11:50.533Z,
  requestId: '8ba2f48a-2ebc-4454-a933-b07c1f9f97b0',
  statusCode: 400,
  retryable: false,
  retryDelay: 880.5633953781091
}

No updates are to be performed.

やりようとしては事前に変更のあるスタックのみ抽出して cdk deploy コマンドを組み立てる方法となりますが、あまりやりたくありませんね。

よって、--method=direct の使い所としては開発時の手動デプロイ時でしょうか。リソースやスタックの数が増えてきた環境ではデプロイ時間が長くなりがちなので、プログレスバーが表示されないことに目を瞑れば、パラメーターを1つ指定するだけでクイックにデプロイして動作確認をできるようになるのはありがたいと思います。

ドキュメントを見てみる

cdk deploy 時の変更セットの制御についてはドキュメントにも記載があります。

下記は記載を日本語訳したものです。

デフォルトでは、CDK はデプロイされる変更を含む CloudFormation 変更セットを作成し、それを実行します。この動作は --method パラメータで制御できます。

- --method=change-set(デフォルト): 変更セットを作成して実行します。
- --method=prepare-change-set: 変更セットを作成しますが、実行しません。これは、変更セットを検査する外部ツールがある場合、または変更セットの承認プロセスがある場合に便利です。
- --method=direct:変更セットを作成せず、変更をすぐに適用します。これは通常、変更セットを作成するよりも少し高速ですが、進行状況の情報が失われます。

変更セットを使用せずに迅速にデプロイするには:
$ cdk deploy --method=direct

変更セットが作成されると、その名前は cdk-deploy-change-set となり、その名前を持つ以前の変更セットは上書きされます。変更セットは、空であっても常に作成されます。後で実行しやすいように、変更セットに名前を付けることもできます。
$ cdk deploy --method=prepare-change-set --change-set-name MyChangeSetName

--method=prepare-change-set パラメーターを使うことにより、変更セットを作成するが実行はしないということもできるんですね。こちらは CDK を使いつつ変更セットによる影響の事前確認や、スタックごとのデプロイのタイミングの細かい制御をしたい時に役立ちそうです。

おわりに

AWS CDK の cdk deploy で変更セットの使用をスキップして、スタックデプロイを高速化してみました。

CI/CD パイプラインの実行時間を短縮して、リリース作業に要する時間を短くできるのでは?と最初は思いましたがそう簡単にはいきませんでした。ただし使い所を選べば有用であることには変わりないので、覚えておいて損は無いと思います。

参考

以上