CloudFormationとCDKの新機能「Pre-deployment Validation」でデプロイ前にエラーを検知してみた

CloudFormationとCDKの新機能「Pre-deployment Validation」でデプロイ前にエラーを検知してみた

CloudFormationのCreateStack / UpdateStack操作でデプロイ前バリデーションが自動実行されるようになりました。CDKではcdk deploy / cdk validateでソースロケーション付きのエラーレポートが得られます。エラーを含むテンプレートが数秒で検知される様子を確認しました
2026.07.01

はじめに

2026年6月30日、AWS CloudFormationのPre-deployment Validationが、従来のChange Set作成時に加えてCreateStack / UpdateStack操作でも実行されるようになりました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/06/aws-cloudformation/

以下が今回のアップデートの概要です。

観点 以前 今回のアップデート
CreateStack / UpdateStack Pre-deployment Validationは未適用(一部エラーはプロビジョニング後に検知) Pre-deployment Validationを自動実行
Change Set バリデーションあり 同左 + 3つの新しい警告チェック追加
エラー検知タイミング リソース作成後(数分〜十数分) リソース作成前(数秒)
CDK 連携 Pre-deployment Validationのソースロケーション連携はなし cdk deploy / cdk validate でソースロケーション付き
オプトアウト N/A --disable-validation / DisableValidation パラメータ

新たに追加された警告チェック(Change Set作成時)は以下の3つです。

  • サービスクォータ超過の検知
  • AWS Config Recorderの競合検出
  • ECRリポジトリ削除準備状況の検知

これらはChange Set作成時に警告として表示されます(今回の検証対象外)。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/validate-stack-deployments.html

検証環境

  • リージョン: ap-northeast-1
  • AWS CLI: 2.35.13
  • CDK: 2.1128.1(Dockerコンテナ上で実行)

CreateStack でのバリデーション

3種類のエラーを埋め込んだテンプレートで create-stack を実行したところ、CREATE_IN_PROGRESS から約4秒で VALIDATION_FAILED となりました。個々のリソースの作成イベントは発生していません。

エラー種別 検知
プロパティ型エラー(VisibilityTimeout に文字列)
無効な enum 値(BillingMode: INVALID_MODE)
存在しないプロパティ名(BucketNam) ❌ 今回は報告されず

以下、テンプレートと出力の詳細です。

テンプレート(プロパティ型エラー + 無効プロパティ名 + 無効 enum 値)

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: cfn-validation-test-queue
      VisibilityTimeout: "not-a-number"  # Integer に文字列

  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketNam: cfn-validation-test-bucket  # タイポ(BucketName)

  MyTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: cfn-validation-test-table
      BillingMode: INVALID_MODE  # 無効な enum 値
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH

実行結果

$ aws cloudformation create-stack \
  --stack-name cfn-prevalidation-test-property-error \
  --template-body file://template-property-error.yaml
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/cfn-prevalidation-test-property-error/...",
    "OperationId": "309700f0-74f8-11f1-ac9b-0652d804920f"
}

数秒後のスタックイベントを確認します。

$ aws cloudformation describe-stack-events \
  --stack-name cfn-prevalidation-test-property-error
- DetailedStatus: VALIDATION_FAILED
  ResourceStatus: CREATE_FAILED
  ResourceStatusReason: >
    Validation failed with 2 error(s). Call DescribeEvents to retrieve
    the full list of issues with resource and property details, resolve
    each error, then retry the operation.
  Timestamp: '2026-07-01T02:54:38.003000+00:00'

CREATE_IN_PROGRESS から約4秒で VALIDATION_FAILED が出ています。個々のリソースの作成イベントは記録されておらず、プロビジョニング前に停止したことが確認できます。

リソース名衝突の検知

S3バケット名に既に使用されている名前を指定した場合も、プロビジョニング前に検知されました。

Resources:
  ConflictBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: aws

  DuplicateBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: aws
- DetailedStatus: VALIDATION_FAILED
  ResourceStatus: CREATE_FAILED
  ResourceStatusReason: >
    Validation failed with 2 error(s).

2つのバケットが同じ名前 aws(既に使用済みの名前)を指定しているため、2件のエラーとして検知されています。

UpdateStack でのバリデーション

手順

  1. 正常なテンプレートでスタックを作成(SQSキュー、VisibilityTimeout: 30)
  2. 不正な変更を含むテンプレートで update-stack を実行(名前衝突するS3バケット追加 + 型エラーのSQSキュー追加)

実行結果

$ aws cloudformation update-stack \
  --stack-name cfn-prevalidation-updatestack-test \
  --template-body file://template-invalid-update2.yaml
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/cfn-prevalidation-updatestack-test/...",
    "OperationId": "87742d60-74fa-11f1-81c1-0a59d997755f"
}
- DetailedStatus: VALIDATION_FAILED
  ResourceStatus: UPDATE_FAILED
  ResourceStatusReason: >
    Validation failed with 2 error(s). Call DescribeEvents to retrieve
    the full list of issues with resource and property details, resolve
    each error, then retry the operation.
  Timestamp: '2026-07-01T03:11:26.274000+00:00'

UpdateStackでも VALIDATION_FAILED が出ました。UPDATE_IN_PROGRESS から約8秒で検知されています。既存リソース(TestQueue)に対する更新イベントは発生しておらず、更新前の状態のままでした(スタックステータスが UPDATE_ROLLBACK_COMPLETE に戻り、リソースのイベントに UPDATE_IN_PROGRESS が記録されていないことで確認)。

--disable-validation との比較

同種のエラーを含むテンプレートを --disable-validation フラグ付きで実行し、従来の挙動と比較します。

$ aws cloudformation create-stack \
  --stack-name cfn-prevalidation-test-no-validation \
  --template-body file://template-missing-required.yaml \
  --capabilities CAPABILITY_IAM \
  --disable-validation

バリデーションがスキップされ、従来どおりリソースのプロビジョニングが開始されます。

- LogicalResourceId: IncompleteTable
  ResourceStatus: CREATE_IN_PROGRESS
  Timestamp: '2026-07-01T02:56:53.124000+00:00'

- LogicalResourceId: IncompleteTable
  ResourceStatus: CREATE_FAILED
  ResourceStatusReason: >
    Properties validation failed for resource IncompleteTable with message:
    #: required key [KeySchema] not found
  Timestamp: '2026-07-01T02:56:53.735000+00:00'

- ResourceStatus: ROLLBACK_IN_PROGRESS
  ResourceStatusReason: >
    The following resource(s) failed to create: [BadTimeout, BadMemory, IncompleteTable].
    Rollback requested by user.
観点 バリデーション有効(デフォルト) --disable-validation
エラー検知タイミング リソースプロビジョニング前 リソース作成試行後
検知までの時間 約4〜8秒 リソース種別に依存(数十秒〜数分)
イベントの流れ CREATE_IN_PROGRESSCREATE_FAILED(DetailedStatus: VALIDATION_FAILED CREATE_IN_PROGRESS → 各リソース CREATE_FAILEDROLLBACK_IN_PROGRESS
リソース作成の有無 作成試行前に停止 一部リソースが作成される場合あり

Change Set でのバリデーション

Change Setでは従来どおりバリデーションが動作します。

$ aws cloudformation create-change-set \
  --stack-name cfn-prevalidation-test-changeset \
  --change-set-name test-changeset \
  --change-set-type CREATE \
  --template-body file://template-property-error.yaml
{
    "Status": "FAILED",
    "StatusReason": "The following hook(s)/validation failed: [AWS::EarlyValidation::PropertyValidation]. To troubleshoot Early Validation errors, use the DescribeEvents API for detailed failure information."
}

Change Setでは、失敗理由に AWS::EarlyValidation::PropertyValidation という検証名が表示されていました。

CDK でのバリデーション

CDKでの動作確認はDockerコンテナ上で実施しました。CDKのL2コンストラクトはTypeScriptの型でプロパティ値を制約するため、単純な型エラーはコンパイル時やCDK側で防がれやすくなります。そこで今回は、CloudFormationレベルの型エラーを意図的に埋め込むためにL1相当の CfnResource を使いました。一方、S3バケット名衝突のようなサービス側依存のエラーはL2コンストラクトでもCloudFormation側で検知されます。

CDK スタック定義

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export class AppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // S3 バケット名衝突
    new s3.Bucket(this, 'ConflictBucket', { bucketName: 'aws' });
    new s3.Bucket(this, 'ConflictBucket2', { bucketName: 'aws' });

    // L1 で型エラーを埋め込み
    new cdk.CfnResource(this, 'BadQueue', {
      type: 'AWS::SQS::Queue',
      properties: {
        QueueName: 'cdk-validation-test-queue',
        VisibilityTimeout: 'not-a-number',
      },
    });
  }
}

cdk deploy の結果

AppStack: creating CloudFormation changeset...
Early validation failed for change set cdk-deploy-change-set:
AppStack/BadQueue  (AWS::SQS::Queue BadQueue)
  Property [VisibilityTimeout] expected type: Integer, found: String
    (at /Resources/BadQueue/Properties/VisibilityTimeout)
Source Location: new AppStack (/app/lib/app-stack.ts:21:22)
                 <anonymous> (/app/bin/app.ts:6:1)

AppStack/ConflictBucket/Resource  (AWS::S3::Bucket ConflictBucketAF941294)
  Resource of type 'AWS::S3::Bucket' with identifier 'aws' already exists.
    (at /Resources/ConflictBucketAF941294)
Source Location: new AppStack (/app/lib/app-stack.ts:11:5)
                 <anonymous> (/app/bin/app.ts:6:1)

AppStack/ConflictBucket2/Resource  (AWS::S3::Bucket ConflictBucket2466B28B1)
  Resource of type 'AWS::S3::Bucket' with identifier 'aws' already exists.
    (at /Resources/ConflictBucket2466B28B1)
Source Location: new AppStack (/app/lib/app-stack.ts:16:5)
                 <anonymous> (/app/bin/app.ts:6:1)

cdk deploy はバリデーションエラーをソースロケーション付き(ファイル名・行番号)で報告します。

cdk validate の結果

cdk validate コマンド(現在unstable)を使うと、ルール名やソース位置を含む整理された形式でエラーを確認できます。

$ cdk validate --unstable=validate
lib/app-stack.ts:16:5
FATAL Resource of type 'AWS::S3::Bucket' with identifier 'aws' already exists. (CloudFormation)
   AppStack/ConflictBucket2/Resource (ConflictBucket2466B28B1)
   Rule NAME_CONFLICT_VALIDATION_VALIDATION_ERROR

lib/app-stack.ts:11:5
FATAL Resource of type 'AWS::S3::Bucket' with identifier 'aws' already exists. (CloudFormation)
   AppStack/ConflictBucket/Resource (ConflictBucketAF941294)
   Rule NAME_CONFLICT_VALIDATION_VALIDATION_ERROR

lib/app-stack.ts:21:22
FATAL Property [VisibilityTimeout] expected type: Integer, found: String (CloudFormation)
   AppStack/BadQueue (BadQueue)
   Rule PROPERTY_VALIDATION_VALIDATION_ERROR

各エラーにルール名が付与されており、CIでのフィルタリングやエラー分類に利用できます。

まとめ

CloudFormationのPre-deployment Validationが、従来のChange Set作成時に加えてCreateStack / UpdateStackでも実行されるようになりました。設定不要でデフォルト有効のため、既存のデプロイワークフローでもそのまま利用できます。

今回の検証では、プロパティ型エラーやリソース名衝突がリソース作成前に検知され、DetailedStatusVALIDATION_FAILED が表示されることを確認しました。CDKでは cdk deploy がソースロケーション付きでエラーを報告し、cdk validate(現時点ではunstable)ではルール名付きの検証結果を確認できます。CI/CDパイプラインでのエラー分類にも活用しやすい形式です。

同日発表のExpressモードではロールバックがデフォルト無効になるため、プロビジョニング前にエラーを検知できるPre-deployment Validationの重要性も増しそうです。Expressモードの詳細は以下の記事で検証しています。

https://dev.classmethod.jp/articles/cloudformation-express-mode-tried/

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事