こんにちは、AWSグループの藤岡です。
前回の記事では、Claude Codeに Agent Plugins for AWS をセットアップし、CDKコード生成を検証しました。
検証にあたって、以下2つの条件で生成結果を比較しました。
- ①プラグインのみ
- ②プラグイン + Guide Layer 有り
生成されたCDKファイルを見て、「②プラグイン + Guide Layer 有り」では実務では注意したいリソース設定が改善されていることを確認しました。
第2回となる本記事では、以下を実施します。
- Claude Code Hooks を使った Sensor Layer の作成
- Sensor Layer の有無による、CDKコードの安全性を検証比較
- 第1回・第2回の結果を踏まえた、考察・まとめ
おさらい
まず、本記事で扱う技術について、簡単におさらいします。
Guide / Sensor とは
本検証では、Claude Code の周辺に以下の2つの制御レイヤーを置いて考えます。
| レイヤー | 役割 | 例 |
|---|---|---|
| Guide Layer | AI の判断を誘導する | CLAUDE.md / AGENTS.md |
| Sensor Layer | 生成後・実行前に機械的に検査する | Hooks + formatter / linter |
Guide Layerは「こういう方針で作ってください」と伝えるためのものです。たとえば、IAM は最小権限にする、ログ保持期間を明示する、削除操作は慎重に扱う、といったルールをAIに渡します。
一方でSensor Layerは実際にできあがったものを検査するためのものです。AIが意図通りに実装したかを、formatter、linter、testなどツールで確認します。
GuideとSensorは補完し合いながらエージェントをサポートします。(以下のようなイメージとなります。)

Claude Code Hooks とは
前回ブログで Guide Layer だけを適用した検証では、強制力がない(あくまで誘導するだけ)ことが課題として残りました。
これを解決するために、Sensor Layerとして Claude Code HookをCDK 検証ツールの実行ポイントとして使います。Claude Code Hooksは、Claude Codeがツールを使う前後に任意のコマンドを実行できる仕組みです。
たとえば、ファイル書き換え直後にテストを実行したり、cdk deploy 直前に cdk diff コマンドを実行・確認したりできます。このようにHookの結果に応じて、Claude に修正を依頼したり、危険なコマンド実行をブロックしたりできます。
Sensor Layer の方針
本記事では、Sensor Layer を CDK(TypeScript) の生成・デプロイを検査するレイヤーとして位置付け、Hook から以下を呼び出します。
- formatter / linter
- CDKテスト(Jest)
cdk synth(cdk-nag評価を含む)cdk diff
これらをエージェントの作業タイミングに合わせて実行します。
| タイミング | Hook | 実行する検査 | 目的 |
|---|---|---|---|
| ファイル生成後 / 保存後 | PostToolUse on Write / Edit |
npm run format:check, npm run lint, npm test, npm run synth |
生成直後に CDK コードの破綻、テスト失敗、cdk-nag finding を検知する |
cdk deploy 直前 |
PreToolUse on Bash |
npm run synth, npm run diff |
cdk-nag finding と削除・置換差分をデプロイ前に検知する |
ここでの cdk-nag は独立した Hook コマンドではなく、CDK 実装に AwsSolutionsChecks を組み込んで、npm run synth の中で評価する前提とします。そのため、ファイル生成後と cdk deploy 直前の両方で cdk-nag がトリガーされます。
また、本検証で意識したポイントは以下です。
- IAM ワイルドカードなど、ベストプラクティスに沿わない箇所の検出は、自前実装せずに、
cdk-nagによる検出(AwsSolutions-IAM5 など)に任せる - CloudWatch Logs の保持期間など、プロジェクト依存の確認は CDK assertions / Jest で検証する
- デプロイ前に
cdk synthとcdk diffを実行し、cdk-nagfinding と削除・置換差分を検知する - Hook は標準ツールを呼び出す薄いゲートにして、CI/CD にも移植しやすくする
CDK プロジェクトの準備
1. CDK TypeScript プロジェクトをセットアップする
本記事では CDK TypeScript のみを扱います。CDK 自体や cdk-nag は他言語でも利用できますが、前回記事と同様に、TypeScript の CDK プロジェクトを前提に、以降の設定を行います。
既存プロジェクトがない場合は、検証用ディレクトリで CDK app を作成します。(第1回の手順と変わりません)
mkdir aws-plugin-guide-validation cd aws-plugin-guide-validation npx cdk init app --language typescript
あわせて、jq が使えることも確認します。(Claude Code が Hook の返り値を扱いやすくするため)
jq --version
2. cdk-nag を導入する
cdk-nag は、Well-Architectedなどを参考にしたルールと、CDK実装との準拠をチェックするツールです。本記事では、IAM ワイルドカードや API Gateway まわりの設定確認に使います。
npm install --save-dev cdk-nag
CDK app の entry point で AwsSolutionsChecks を有効化します。例として bin/cdk.ts に追加します。
#!/usr/bin/env node import * as cdk from 'aws-cdk-lib/core'; import { AwsSolutionsChecks } from 'cdk-nag'; // 追加 import { CdkStack } from '../lib/cdk-stack'; const app = new cdk.App(); new CdkStack(app, 'CdkStack', { }); cdk.Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true })); // 追加
これにより、cdk synth 実行時(合成テンプレート作成時)に、ルールセットをもとにしたチェックが実行されます。たとえば IAM ポリシーの Action: "dynamodb:*" や Resource: "*" は、AwsSolutions-IAM5 の finding として検出できます。
3. npm scripts を定義する
Hook から直接 cdk-nag の内部実装を呼ぶのではなく、標準の npm scripts を実行します。これにより、手動実行、Hooks、CI/CD で同じコマンドを共有できます。
package.json に以下を追加します。
{ "scripts": { "format:check": "prettier --check \"**/*.ts\"", "lint": "eslint . --ext .ts", "test": "jest", "synth": "cdk synth", "diff": "cdk diff" } }
formatter / linter をインストールします。
npm install --save-dev prettier eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin npm run format:check npm run lint npm test npm run synth
CloudWatch Logs の保持期間は、Guide Layer で構築前に確認させます。Sensor Layer では CDK assertions(Jest)を使い、テストケースによって合成テンプレートの RetentionInDays を検査します。
import { App } from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; import { AwsPluginGuideValidationStack } from '../lib/aws-plugin-guide-validation-stack'; test('CloudWatch Logs retention is explicitly configured', () => { const app = new App(); const stack = new AwsPluginGuideValidationStack(app, 'TestStack'); const template = Template.fromStack(stack); const logGroups = template.findResources('AWS::Logs::LogGroup'); expect(Object.keys(logGroups).length).toBeGreaterThan(0); for (const resource of Object.values(logGroups)) { expect(resource.Properties).toHaveProperty('RetentionInDays'); } });
Hook 実装
ここから、Claude Code Hooks で使う2つのスクリプトを用意します。1つ目は CDK ファイル生成・編集直後のチェック、2つ目は cdk deploy 直前のゲートです。
ディレクトリ作成
Hook スクリプトを置くディレクトリを作成します。
mkdir -p .claude/hooks
⚠️以降は、
package.jsonとcdk.jsonがある CDK app のルートで Claude Code を開いている前提です。
センサー①:ファイル生成後の CDK チェック
Write / Edit の後に formatter / linter / CDK assertions / cdk synth を実行します。(cdk-nag は cdk synth 実行時に評価されます)
実装ファイル: .claude/hooks/run-cdk-checks.sh
#!/usr/bin/env bash
set -euo pipefail
cd "$CLAUDE_PROJECT_DIR"
if [[ ! -f package.json || ! -f cdk.json ]]; then
exit 0
fi
run_check() {
local name="$1"
shift
if ! output="$("$@" 2>&1)"; then
echo "CDK Sensor failed: ${name}" >&2
echo "Command: $*" >&2
echo "$output" >&2
exit 2
fi
}
run_check format-check npm run format:check
run_check lint npm run lint
if node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)" >/dev/null 2>&1; then
run_check test npm test
fi
run_check synth npm run synth
実行権限を付与します。
chmod +x .claude/hooks/run-cdk-checks.sh
この Hook は、構文崩れ、lint 違反、テスト失敗、cdk-nag finding を Claude に返すためのものです。Hook 内では判定ロジックを増やさず、npm scripts の結果を stderr で返します。
センサー②:cdk deploy 直前の cdk diff ゲート
cdk deploy の直前に cdk synth と cdk diff を実行します。cdk synth で cdk-nag を再評価し、cdk diff で削除差分を検知します。
実装ファイル: .claude/hooks/guard-cdk-deploy.sh
#!/usr/bin/env bash
set -euo pipefail
HOOK_INPUT="$(cat)"
COMMAND="$(printf '%s' "$HOOK_INPUT" | jq -r '.tool_input.command // ""')"
case "$COMMAND" in
*"cdk deploy"*|*"npx cdk deploy"*) ;;
*) exit 0 ;;
esac
cd "$CLAUDE_PROJECT_DIR"
if [[ ! -f package.json || ! -f cdk.json ]]; then
exit 0
fi
if ! synth_output="$(npm run synth 2>&1)"; then
echo "$synth_output" >&2
jq -n --arg reason "cdk synth failed before deploy. Review the hook output before running deploy." '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: $reason
}
}'
exit 0
fi
if ! diff_output="$(npm run diff 2>&1)"; then
echo "$diff_output" >&2
jq -n --arg reason "cdk diff failed before deploy. Review the hook output before running deploy." '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: $reason
}
}'
exit 0
fi
if echo "$diff_output" | grep -E '(^|\s)(destroy|Delete|DELETE|will be destroyed|Replacement)' >/dev/null; then
echo "$diff_output" >&2
jq -n --arg reason "cdk diff detected a destructive or replacement change. Review the hook output before running deploy." '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: $reason
}
}'
exit 0
fi
exit 0
実行権限を付与します。
chmod +x .claude/hooks/guard-cdk-deploy.sh
この Hook は、cdk diff の実差分を見て、削除・置換の疑いがある場合に cdk deploy を中止します。
Hooks の設定
.claude/settings.json を作成し、2つの Hook を登録します。
{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/run-cdk-checks.sh", "statusMessage": "CDK format/lint/synth/cdk-nag checks are running...", "timeout": 120 } ] } ], "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard-cdk-deploy.sh", "statusMessage": "CDK pre-deploy sensor is running...", "timeout": 180 } ] } ] } }
それぞれの Hook は、前述のSensor Layer の方針をベースに設定しました。
PostToolUse はフィードバック用の Hook です。保存自体はブロックせず、失敗時に Claude Code へエラー出力を返して修正させます。
PreToolUse は実行前ゲートです。cdk deploy を含む Bash コマンドに反応し、cdk synth や cdk diff に問題があればデプロイを許可しません。
検証③ Sensor Layer の検証
前回の検証①(Plugin単体)、検証②(Guide適用)に続き、検証③では Hooks を適用した状態で同じシナリオを実行します。
シナリオ(ⅰ):テキストメモAPIのCDKテンプレート生成
前回の検証①・②と同様に、cdk init した初期プロジェクト状態で、以下のように入力します。
テキストメモを登録・取得するサーバーレスAPIを AWS CDK TypeScript で構築してください。実際のデプロイはまだ実行しないでください。
入力すると、まずは Guide(AGENT.md や CLAUDE.md)に則って、ヒアリングやファイル作成が始まりました。

Claude Code による生成後、Sensor によってテストが実行されますが、テストが実装を踏まえていないため、エラーをもとに CDK assertions(テストケース)を修正しようと自律的に動きました。

そのまま自律的に、生成と Sensor Layer によるチェックを繰り返し、デプロイ直前まで到達しました。テストケースによる評価は追加されていますが、ここまでは ②(Guide適用)と大きな差分はありません。

シナリオ(ⅱ):CDKデプロイの実行
続いて、Claude Code にデプロイを指示します。(生成された CDK スタックに cdk-nag が設定されていることを事前に確認済みです。)
デプロイを指示すると、Hook が先に cdk synth を実行します。その過程で cdk-nag の評価が走り、finding が出たためデプロイは中止されました。

cdk-nag では、以下を含む合計6件の finding が出ました。
- DynamoDB テーブル:PITRが有効化されていない
- Lambda 関数:コンテナランタイムでない場合に、最新ランタイムバージョンを使用していない
- IAM ポリシー:AWS マネージドポリシー(AWSLambdaBasicExecutionRole)を使用しているため、権限範囲が広い
今度はもう1つのデプロイシナリオとして、先ほどの cdk-nag finding を解消したうえで、デプロイ済みリソースの削除が発生するように CDK コードを修正します。その状態で、Claude Code にデプロイを依頼します。
すると、以下のようにcdk diff によるリソース削除を検知したことで、指示のとおりにデプロイを継続せずに中止をしました。これも期待通りにSensor Layerが作動してくれました。

この検証で、Sensor Layer が「生成後に検査し、問題があれば止める」役割を担えることを確認できました。Hook で評価ポイントを固定すると、Claude Code の作業ループに検査結果を戻せます。
また、cdk deploy 直前の cdk synth(cdk-nag)と cdk diff による評価ゲートは、Guide Layer では代替しにくい領域です。削除・置換差分を一度止めて確認できるため、安全側に倒しやすくなります。
検証①②③ の整理・考察
第1回の結果とあわせると、各レイヤーの違いは次のように整理できます。
| 観点 | ①Plugin単体 | ②Guideあり | ③Guide+Sensor |
|---|---|---|---|
| IAMポリシー | ワイルドカードが利用されるケースあり | 明示的な action / resource を指定して生成 | cdk-nag が設定不備として検出 |
| CloudWatch Logs | 保持期間の明示なし | 未指定なら構築前に確認 | CDK assertions / Jest で保持期間を検査 |
| API Gateway | アクセスログ未検討 | ログ・メトリクス要否を確認 | cdk-nag が設定不足を検出 |
| デプロイ前差分 | 未確認 | 確認を促す | cdk synth(cdk-nag)と cdk diff で deploy を止める |
Plugin単体でも、サーバーレスAPIの骨格は生成できます。簡単な検証であれば、ここまででも十分です。
Guide Layer を加えると、IAM やログ保持期間など、レビューで見たい観点を生成前に意識させられます。ただし、Guide Layer は「何に気をつけるか」を伝える層です。生成結果が基準を満たすか、デプロイ直前に危険な差分がないかまでは保証しません。
Sensor Layer を加えると、format / lint / test / synth / cdk-nag / diff の結果を Claude Code の作業ループに戻せます。問題があればその場で修正させ、deploy 前には Hook で止められます。
今回の検証では、Guide が生成前の判断を支え、Sensor が生成後・実行前の確認を担う、という両面でのClaude Code のサポートが有効だと分かりました。
まとめ
本記事では、Claude Code Hooks による Sensor Layer を、CDK の標準検査フローとして実装しました。
第1回・第2回の結果を踏まえて、以下ポイントを押さえることが重要です。
- Guide Layer で、CDK の設計方針を誘導する
- PostToolUse Hook で、ファイル生成後に format / lint / test / synth(
cdk-nag)を走らせる - PreToolUse Hook で
cdk deploy直前に synth(cdk-nag)とcdk diffを確認する
この構成により、生成直後の不備は Claude Code の修正ループへ戻し、デプロイ直前の確認が必須な状態は Hook で止められます。
Agent Plugins for AWS は AWS の作法を渡し、Guide はプロジェクト固有の判断基準を渡し、Sensor は生成物と実行内容を機械的に確認します。まずはこの3つをすべて導入しつつ、プロジェクトに合わせて Guide と Sensor を育てていくのが現実的だと感じました。
本記事が、エージェンティックコーディングに興味を持たれた方のお役に立てば幸いです。
以上となります。2回に渡って読んでいただき、ありがとうございました。