1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CDK の検証コマンド lsp / validate / drift / diagnose の利用場面

1
Posted at

はじめに

CDK は cdk synth が通っても、cdk deploy で CloudFormation 側が失敗することがあります。

最近の CDK CLI には、この失敗を手前で見つけたり、原因を調べたりするコマンド(lsp / validate / diagnose)が追加されています。既存の drift と合わせて試します。

コマンド できること 使う場面
cdk lsp エディタに CDK の違反を波線で出す コードを書いている最中
cdk validate デプロイせずに、デプロイ前の検証だけを行う commit / PR の前
cdk drift 手作業で変更されたリソースを見つける PR の CI
cdk diagnose 失敗したデプロイの原因を後から表示する デプロイ失敗後

この記事では、4 つを手順どおりに 1 つずつ実行して確かめます。

やってみた

前提

  • CDK CLI 2.1143.0(cdk lsp は 2.1132.0 以上が必要)、aws-cdk-lib 2.271.0、cdk-nag 3.0.2
  • ap-northeast-1(東京リージョン)
  • cdk bootstrap 済み
  • validate と diagnose は --unstable フラグが必要です(diagnose は CDK CLI の README に記載。validate は 2.1143.0 で付けないとエラーになります)

手順 0:プロジェクトを作る

バケットとキューを 1 つずつ持つスタックを作り、合成時のポリシー検証に cdk-nag を登録します。

npm install -g aws-cdk@latest
mkdir cdk-verify && cd cdk-verify
cdk init app --language typescript
npm install cdk-nag@3

ちなみに、cdk-nag v3 については過去に以下の記事も書いていますので参考に。

bin/cdk-verify.ts と lib/cdk-verify-stack.ts を、次の内容で上書きします。

bin/cdk-verify.ts
bin/cdk-verify.ts
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib/core';
import { AwsSolutionsChecks } from 'cdk-nag';
import { CdkVerifyStack } from '../lib/cdk-verify-stack';

const app = new cdk.App();

// cdk-nag v3 を合成時のポリシー検証プラグインとして登録
cdk.Validations.of(app).addPlugins(new AwsSolutionsChecks(app));

new CdkVerifyStack(app, 'CdkVerifyStack', {
  env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
});
lib/cdk-verify-stack.ts
lib/cdk-verify-stack.ts
import * as cdk from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as sqs from 'aws-cdk-lib/aws-sqs';

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

    const bucket = new s3.Bucket(this, 'DataBucket', {
      enforceSSL: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
    // アクセスログ未設定(AwsSolutions-S1)は検証用なので許容
    cdk.Validations.of(bucket).acknowledge({ id: 'AwsSolutions-S1', reason: '検証用' });

    const queue = new sqs.Queue(this, 'JobQueue', {
      visibilityTimeout: cdk.Duration.seconds(300),
      enforceSSL: true,
    });
    // DLQ 未設定(AwsSolutions-SQS3)は検証用なので許容
    cdk.Validations.of(queue).acknowledge({ id: 'AwsSolutions-SQS3', reason: '検証用' });
  }
}

手順 1:cdk validate(オフライン)

--no-online を付けると、cdk-nag などのポリシー検証だけを行います。

わざと違反を作るため、11 行目のバケットの enforceSSL をコメントアウトして実行します。

lib/cdk-verify-stack.ts(10〜13 行目)
    const bucket = new s3.Bucket(this, 'DataBucket', {
      // enforceSSL: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
npx cdk --unstable=validate validate --no-online

スクリーンショット 2026-09-29 0.50.34.png

lib/cdk-verify-stack.ts:11:20 のように、違反のあるリソースを作っている行(new s3.Bucket()が表示されます。

確認できたら、コメントアウトを戻します。

手順 2:cdk lsp(VS Code に波線を出す)

cdk lsp は、synth の結果(cdk.out)にある検証レポートを、エディタのソース行に波線として返す Language Server です(cdk-explorer の README)。

公式のエディタ拡張はまだないため、README の案内どおり汎用拡張「Generic LSP Client」でつなぎます。

この方法で使えるのは波線とホバーだけで、synth はターミナルで行います。

拡張を入れます(code コマンドが無い場合は、VS Code のコマンドパレットで「Shell Command: Install 'code' command in PATH」を実行)。

code --install-extension zsol.vscode-glspc

コマンドパレット →「Preferences: Open User Settings (JSON)」に追記します(README の指示どおり、ワークスペース設定ではなくユーザー設定に書きます)。

settings.json
{
  "glspc.server.command": "cdk",
  "glspc.server.commandArguments": ["lsp"],
  "glspc.server.languageId": ["typescript", "python"]
}

手順 1 と同じく enforceSSL をコメントアウトして synth し、ターミナルから VS Code を開きます。synth は cdk-nag のエラーを表示して終わりますが、cdk.out に検証レポートは出力されます。

npx cdk synth -q
code .

スクリーンショット 2026-09-29 0.54.21.png

lib/cdk-verify-stack.ts の 11 行目 new s3.Bucket( に波線が付き、ホバーすると cdk-nag の指摘が表示されます。

確認できたら、コメントアウトを戻します。

手順 3:cdk validate(オンライン)

オプションなし(--online が既定)で実行すると、テンプレートを CloudFormation のデプロイ前検証に送ります。

CloudFormation は、プロパティの構文やリソース名の衝突などをデプロイ前に検証します(CloudFormation のドキュメント)。

AWS の認証情報と bootstrap が必要です。

名前の衝突を起こすため、先に同じ名前のバケットを作ります。

ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
aws s3api create-bucket --bucket cdk-verify-existing-$ACCOUNT \
  --create-bucket-configuration LocationConstraint=ap-northeast-1

バケットに bucketName を 1 行追加して、実行します。

lib/cdk-verify-stack.ts(10〜14 行目)
    const bucket = new s3.Bucket(this, 'DataBucket', {
      bucketName: `cdk-verify-existing-${this.account}`,
      enforceSSL: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
npx cdk --unstable=validate validate

スクリーンショット 2026-09-29 1.16.37.png

FATAL ... already exists と NAME_CONFLICT_VALIDATION_VALIDATION_ERROR が、ソースの行付きで表示されます。 デプロイはされないので、スタックは作られません。確認できたら、追加した bucketName の行を消し、バケットを削除します。

aws s3 rb s3://cdk-verify-existing-$ACCOUNT

手順 4:cdk drift

一度デプロイし、手作業での変更を想定して、キューの可視性タイムアウトを CLI で 300 秒 → 60 秒に変えます。

npx cdk deploy --require-approval never
Q=$(aws cloudformation describe-stack-resources --stack-name CdkVerifyStack \
  --query "StackResources[?ResourceType=='AWS::SQS::Queue'].PhysicalResourceId" --output text)
aws sqs set-queue-attributes --queue-url "$Q" --attributes VisibilityTimeout=60
npx cdk drift --fail

スクリーンショット 2026-09-29 1.34.22.png

/VisibilityTimeout が 300 → 60 と表示され、--fail を付けているので exit code 1 で終了します。

CloudFormation のドリフト検出は、テンプレートで明示的に設定したプロパティだけが対象です(ドリフト検出のドキュメント)。

2 unchecked は、ドリフト検出に対応していないバケットポリシーとキューポリシーです(--verbose で確認できます)。

手順 5:cdk diagnose

デプロイ時に失敗するリソースとして、存在しないマネージドポリシーを付けた IAM ロールを追加します。

4 行目(sqs の import)の下に import を 1 行、コンストラクタの最後にロールを追加します。

lib/cdk-verify-stack.ts(5 行目に追加)
import * as iam from 'aws-cdk-lib/aws-iam';
lib/cdk-verify-stack.ts(コンストラクタの最後に 1 行空けて追加)

    // 存在しないマネージドポリシーを付けたロール(デプロイ時に失敗する)
    const role = new iam.Role(this, 'BrokenRole', {
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
      managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('ThisPolicyDoesNotExist')],
    });
    // AWS マネージドポリシーの使用(AwsSolutions-IAM4)は検証用なので許容
    cdk.Validations.of(role).acknowledge({
      id: 'AwsSolutions-IAM4[Policy::arn:<AWS::Partition>:iam::aws:policy/ThisPolicyDoesNotExist]',
      reason: '検証用',
    });

このロールはオンラインの validate では検出されず(Validation did not find any problems.)、デプロイで失敗します。

npx cdk --unstable=validate validate
npx cdk deploy --require-approval never
npx cdk --unstable=diagnose diagnose

スクリーンショット 2026-09-29 1.37.51.png

diagnose で、失敗したリソース(BrokenRole)、原因(does not exist or is not attachable)、ソースの行(cdk-verify-stack.ts:26:18)が表示されます。

README によると、cdk deploy が失敗時に行う診断を後から実行するコマンドで、CI/CD でデプロイしている場合などに使えます。

手順 6:後片付け

npx cdk destroy --force

開発フローのどこで回すか

タイミング 回すもの 理由
ファイル編集 cdk lsp エディタ上で違反の行が分かる
git commit cdk validate --no-online AWS の認証情報なしで回せる
PR の CI cdk validate / cdk drift --fail AWS 上の状態と突き合わせる。exit code でゲートにできる
デプロイ失敗時 cdk diagnose 失敗の原因を後から確認できる

まとめ

  • cdk validate のオンライン検証で、名前の衝突のような「デプロイしないと分からない」失敗をデプロイ前に検出できました
  • ただし存在しないポリシーのように検出できないものもあるので、drift や diagnose と組み合わせるのがよさそうです
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?