Claude CodeでAWS CloudFormation/CDKを安全に使う実践ガイド
Claude CodeでAWS CDK/CloudFormationを安全にレビューし、差分・IAM・ドリフト・ロールバックまで実践解説。
AWSの設定をコンソールで少しずつ直していると、あとから「本番はなぜこの値なのか」「検証環境と何が違うのか」を説明できなくなります。CloudFormationとAWS CDKは、VPC、IAM、S3、DynamoDB、Lambdaなどの設定をコードとして残すための仕組みです。IaC、つまりInfrastructure as Codeは「インフラの設計書を、そのまま実行できるコードにする」考え方です。
Claude Codeはここでかなり役に立ちます。ただし、任せ方を間違えると危険です。Action: "*"のIAMポリシー、削除保護のないDB、NAT Gatewayを含む検証環境、レビューされていないcdk deployは、便利な自動化の顔をした事故原因になります。
この記事では、Claude Codeを「インフラを勝手にデプロイする担当」ではなく、「設計のたたき台を作り、差分を説明し、危険な変更を見つけるレビュー担当」として使う流れをまとめます。Masaが案件で痛感したのは、AIにコードを書かせることより、AIに壊してはいけないものを明示してレビューさせることの方が重要だという点でした。
初心者向けに用語も整理します。CloudFormationはAWS公式のテンプレート実行サービスです。CDK、Cloud Development KitはTypeScriptなどで書いたコードをCloudFormationテンプレートに変換する開発キットです。スタックは、CloudFormationがまとめて作成・更新・削除するリソースの単位です。ドリフトは、コードで管理している値と実際のAWSリソースがずれた状態です。
この記事は2026年6月3日時点のAWS公式ドキュメントを前提にしています。特に次の公式情報を基準にしました。
- AWS CDK Developer Guide
- AWS CDK CLI deploy command
- AWS CDK CLI diff command
- CloudFormation change sets
- CloudFormation drift detection
- CloudFormation stack failure options
- IAM security best practices
- AWS CDK security best practices
Claude Codeに任せる範囲を決める
最初に決めるべきなのは、Claude Codeに何をさせ、何をさせないかです。おすすめは次の分担です。
| 作業 | Claude Codeに任せる | 人間が確認する |
|---|---|---|
| 要件整理 | リソース一覧、環境差分、依存関係の整理 | 本当に必要なリソースか |
| テンプレート作成 | CloudFormation/CDKの初稿 | 命名、削除保護、課金影響 |
| IAM設計 | 必要アクションの候補出し | ResourceとConditionが狭いか |
| 差分レビュー | cdk diffやchange setの要約 | 削除・置換・権限拡大の承認 |
| 障害対応 | ログの読み解き、修正案 | ロールバック方針と本番反映 |
安全な運用の基本は、Claude Codeに「作って」ではなく「レビューして」と言うことです。たとえば「このCDKコードを本番に出してよいか。置換、削除、IAM拡大、公開アクセス、月額コスト増だけを表で指摘して」と頼むと、単なる生成よりも実務に近い結果になります。
flowchart LR
A["要件を文章で書く"] --> B["Claude CodeでIaC初稿を作る"]
B --> C["人間がリソース名とコストを確認"]
C --> D["cdk diff / change setを作る"]
D --> E["Claude Codeに危険差分を説明させる"]
E --> F["承認後にdeploy"]
F --> G["drift detectionとrollback手順を記録"]
ユースケース1: 既存AWS設定をCloudFormationに落とす
既存環境をいきなり大きなCDKアプリに移す必要はありません。まずは影響の小さいリソースをCloudFormationでコード化し、Claude Codeにレビューさせるのが堅実です。次の例は、プライベートS3バケットと、そのバケットだけを読めるLambda用IAMロールを作ります。デプロイするとIAMロールが作られるため、CAPABILITY_NAMED_IAMを明示します。
mkdir cfn-iac-review-demo
cd cfn-iac-review-demo
# 次のYAMLを cfn-safe-iac-demo.yaml として保存
AWSTemplateFormatVersion: "2010-09-09"
Description: "ClaudeCodeLab safe IaC review demo: private S3 bucket and least-privilege Lambda role"
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
ProjectName:
Type: String
Default: cclab-iac-demo
AllowedPattern: "^[a-z0-9][a-z0-9-]{2,24}$"
Resources:
DemoBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
BucketName: !Sub "${ProjectName}-${Environment}-${AWS::AccountId}-${AWS::Region}"
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
Tags:
- Key: Project
Value: !Ref ProjectName
- Key: Environment
Value: !Ref Environment
DemoReaderRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${ProjectName}-${Environment}-reader-${AWS::Region}"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: ReadOnlyDemoBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: ListOnlyThisBucket
Effect: Allow
Action:
- s3:ListBucket
Resource: !GetAtt DemoBucket.Arn
- Sid: ReadObjectsOnly
Effect: Allow
Action:
- s3:GetObject
Resource: !Sub "${DemoBucket.Arn}/*"
Outputs:
BucketName:
Value: !Ref DemoBucket
ReaderRoleArn:
Value: !GetAtt DemoReaderRole.Arn
実行前に、Claude Codeへ次のようにレビューを依頼します。
claude -p "
cfn-safe-iac-demo.yamlをCloudFormationテンプレートとしてレビューして。
次の観点だけを表で指摘して:
1. 公開アクセスになる可能性
2. IAMのResourceが広すぎる箇所
3. 削除・置換時にデータを失う箇所
4. 月額コストが発生する可能性
5. 本番適用前にchange setで確認すべき項目
"
問題がなければ、まずchange setで確認します。aws cloudformation deployは内部的にchange setを使いますが、レビューを丁寧にしたい本番では、明示的に作って中身を見る方が安心です。
aws cloudformation create-change-set \
--stack-name cclab-iac-demo-dev \
--change-set-name review-20260603-001 \
--template-body file://cfn-safe-iac-demo.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters ParameterKey=Environment,ParameterValue=dev ParameterKey=ProjectName,ParameterValue=cclab-iac-demo
aws cloudformation describe-change-set \
--stack-name cclab-iac-demo-dev \
--change-set-name review-20260603-001
この段階で見るべき単語は、Add、Modify、Remove、Replacementです。特にReplacement: Trueは「同じリソースを更新する」のではなく「作り直す」可能性を示します。S3、RDS、DynamoDBでこれを見落とすと、データ移行や停止時間の話になります。
ユースケース2: CDK TypeScriptで安全な最小構成を作る
新規開発ならCDK TypeScriptが扱いやすいです。型補完が効くため、Claude Codeが出したコードを人間も読みやすく、レビューもしやすくなります。次の例は、低コストで試せるDynamoDB、S3、Lambdaの最小構成です。Lambdaのコードはインラインなので、追加ファイルなしでcdk synthできます。
mkdir cdk-iac-review-demo
cd cdk-iac-review-demo
npm init -y
npm install aws-cdk-lib constructs
npm install --save-dev aws-cdk typescript ts-node @types/node
mkdir bin lib
{
"app": "npx ts-node --prefer-ts-exts bin/app.ts"
}
// bin/app.ts
import * as cdk from "aws-cdk-lib";
import { IacReviewDemoStack } from "../lib/iac-review-demo-stack";
const app = new cdk.App();
new IacReviewDemoStack(app, "IacReviewDemoStack", {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION ?? "ap-northeast-1",
},
});
// lib/iac-review-demo-stack.ts
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as logs from "aws-cdk-lib/aws-logs";
import * as s3 from "aws-cdk-lib/aws-s3";
export class IacReviewDemoStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const stage = this.node.tryGetContext("stage") ?? "dev";
const isProd = stage === "prod";
const table = new dynamodb.Table(this, "AppTable", {
partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
pointInTimeRecovery: isProd,
deletionProtection: isProd,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
});
const bucket = new s3.Bucket(this, "PrivateAssetsBucket", {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
enforceSSL: true,
encryption: s3.BucketEncryption.S3_MANAGED,
versioned: true,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: !isProd,
});
const fn = new lambda.Function(this, "ApiHandler", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromInline(`
exports.handler = async () => ({
statusCode: 200,
body: JSON.stringify({
tableName: process.env.TABLE_NAME,
bucketName: process.env.BUCKET_NAME
})
});
`),
environment: {
TABLE_NAME: table.tableName,
BUCKET_NAME: bucket.bucketName,
STAGE: stage,
},
timeout: cdk.Duration.seconds(10),
memorySize: 256,
logRetention: logs.RetentionDays.ONE_WEEK,
});
table.grantReadWriteData(fn);
bucket.grantPut(fn);
fn.addToRolePolicy(
new iam.PolicyStatement({
sid: "DenyInsecureS3Transport",
effect: iam.Effect.DENY,
actions: ["s3:*"],
resources: [bucket.bucketArn, bucket.arnForObjects("*")],
conditions: { Bool: { "aws:SecureTransport": "false" } },
}),
);
cdk.Tags.of(this).add("Project", "ClaudeCodeLab");
cdk.Tags.of(this).add("Stage", stage);
new cdk.CfnOutput(this, "FunctionName", { value: fn.functionName });
new cdk.CfnOutput(this, "BucketName", { value: bucket.bucketName });
new cdk.CfnOutput(this, "TableName", { value: table.tableName });
}
}
最初に実行するのはdeployではありません。synthとdiffです。
npx cdk synth -c stage=dev
npx cdk diff -c stage=dev
claude -p "
このcdk diffをレビューして。
削除、置換、IAM権限拡大、S3公開、DynamoDB課金、Lambdaの環境変数漏えいの観点だけで指摘して。
$(npx cdk diff -c stage=dev 2>&1)
"
ここでClaude Codeに期待するのは、コードの称賛ではなく赤信号の抽出です。たとえばautoDeleteObjects: !isProdは検証環境では便利ですが、本番で有効になっていたら危険です。bucket.grantPut(fn)はPutObject中心の権限なので広すぎませんが、読み取りも必要になった瞬間にgrantReadWriteへ広げる前に、実際のユースケースを再確認するべきです。
ユースケース3: 本番差分を説明させる
CDKの怖さは、TypeScriptの小さな変更がCloudFormation上では大きな置換になることです。Claude Codeには、差分を「開発者向け」ではなく「承認者向け」に翻訳させます。
claude -p "
以下のcdk diffを、非AWS専門のプロダクト責任者にも分かる言葉で要約して。
出力は次の列にして:
- 変更種別
- 対象リソース
- ユーザー影響
- セキュリティ影響
- コスト影響
- 承認前に聞くべき質問
$(npx cdk diff -c stage=prod 2>&1)
"
本番レビューで特に見るのは、IAMポリシーのActionとResource、Security Groupの0.0.0.0/0、RDSやDynamoDBの削除保護、S3の公開設定、CloudFrontやNAT Gatewayの追加です。NAT Gatewayは検証環境でも固定費が出やすく、Claude Codeに「この構成の月額コストが増える可能性を列挙して」と聞く価値があります。
ユースケース4: ロールバックとドリフト調査を標準化する
デプロイが失敗したときに、あわててコンソールで直すとドリフトが起きます。CloudFormationのロールバック状態、UPDATE_ROLLBACK_FAILED、ROLLBACK_COMPLETEの扱いは、公式ドキュメントを見ながら対応するべき領域です。
aws cloudformation describe-stacks --stack-name cclab-iac-demo-dev
aws cloudformation detect-stack-drift --stack-name cclab-iac-demo-dev
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id YOUR_DETECTION_ID
Claude Codeへの依頼は、原因推測と次アクションの切り分けに限定します。
claude -p "
CloudFormationスタックがUPDATE_ROLLBACK_FAILEDになった。
以下のeventsを読み、原因候補、触ってよいリソース、触ってはいけないリソース、AWS公式ドキュメントで確認すべき手順を分けて説明して。
$(aws cloudformation describe-stack-events --stack-name cclab-iac-demo-dev 2>&1)
"
ここで大事なのは、Claude Codeが「コンソールで手動修正しましょう」と言った場合に、その修正を後から必ずIaCへ戻すことです。手動修正は緊急避難であって、恒久対応ではありません。
具体的な落とし穴
IAMを広げすぎる。 Claude Codeは動くコードを優先してAction: "*"やResource: "*"を提案することがあります。IAMは「必要な操作を、必要な対象にだけ」です。S3ならバケットARNとオブジェクトARNを分け、DynamoDBならテーブルARNに限定します。
差分を読まずにcdk deployする。 小さなプロパティ変更でも、CloudFormation上では置換になることがあります。特に名前付きリソース、暗号化設定、サブネット、DBエンジン、キー設定は慎重に見ます。
検証環境のコストを軽視する。 ALB、NAT Gateway、RDS、OpenSearch、常時稼働ECSは、使っていなくても費用が出ます。Claude Codeに「無料枠ではなく月額固定費を出すリソースだけ挙げて」と聞くと、レビューの観点が変わります。
削除ポリシーを環境で分けない。 開発では削除しやすく、本番では保持する設計が必要です。CDKならRemovalPolicy.DESTROYとRETAINをstageで切り替えます。ただし、検証環境でautoDeleteObjectsを使う場合も、本番で絶対に有効化しないガードが必要です。
Secretsをテンプレートに直書きする。 パスワードやAPIキーをCloudFormationパラメータやCDKコードへ直接書くと、Git履歴やスタック履歴に残ります。Secrets ManagerやSSM Parameter Storeを使い、Claude Codeにも「秘密値を出力しない」と明示します。
ドリフトを放置する。 コンソールで修正したSecurity Group、手で変えたS3ポリシー、手動で増やしたLambda環境変数は、次のデプロイで戻ったり、差分に出なかったりします。月1回だけでもドリフト検出を定例化すると、事故の芽を早く見つけられます。
Claude Code用レビュープロンプト
本番前のレビューでは、このまま貼れるプロンプトを使っています。
あなたはAWS CloudFormation/CDKのレビュアーです。
次のIaC差分を、公開前レビューとして厳しく見てください。
必ず確認する観点:
- IAMのAction/Resource/Conditionが最小権限か
- Security GroupやS3が意図せず公開されないか
- RDS/DynamoDB/S3/Secretsが削除または置換されないか
- ALB/NAT Gateway/RDSなど月額固定費が増えないか
- CloudFormation driftが起きていそうな変更か
- ロールバック時に手動対応が必要なリソースはあるか
出力:
1. 即修正すべき問題
2. 承認者に確認すべき質問
3. deploy前に実行するコマンド
4. deploy後に確認するコマンド
Claude Codeに「厳しく」と書くのは飾りではありません。生成タスクでは便利さを優先しがちですが、レビュータスクでは疑う姿勢を明示した方が実務に近い指摘が出ます。
ClaudeCodeLabで学びを深める
IAMの最小権限をさらに掘り下げるなら、Claude CodeとAWS IAMの実践ガイドが関連します。Lambda中心の構成を組むならClaude CodeとAWS Lambdaガイド、APIの入口を設計するならClaude CodeとAWS API Gateway、データ層ならClaude CodeとAWS DynamoDBも合わせて読むと、スタック全体のレビュー観点がつながります。
チームでIaCレビューを型化したい場合は、ClaudeCodeLabの実践教材とチーム向けトレーニングも用意しています。記事で紹介したプロンプトを、社内のPull Requestテンプレートやリリースチェックリストに合わせて調整すると、Claude Codeの出力が「個人の便利ツール」から「チームの品質ゲート」に変わります。
まとめ
Claude CodeとAWS CloudFormation/CDKの相性は良いです。ただし、最も価値が出るのは自動生成そのものではなく、差分、IAM、コスト、削除、ロールバックを人間が見落とさないようにするレビュー補助です。CDKならnpx cdk synth、npx cdk diff、CloudFormationならchange setとdrift detectionを使い、Claude Codeには危険な変更を説明させる。この流れを守るだけで、IaCの導入はかなり安全になります。
実際に試した結果、Claude Codeに「作って」とだけ頼んだ時より、「最小権限、削除保護、コスト、ロールバック、ドリフトの観点でレビューして」と頼んだ時の方が、本番前に役立つ指摘が明らかに増えました。小さなS3とIAMロールの例でも、change setで置換や削除を確認し、diffを説明させる流れを入れるだけで、レビュー会話が具体的になります。AIはデプロイ担当ではなく、厳しい二人目のレビュアーとして使うのが一番実務的です。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
ObsidianメモをCLAUDE.mdに変えるClaude Code運用: 文脈を毎回説明しない仕組み
Obsidianの作業メモからCLAUDE.md用の運用ノートを作り、Claude Codeに安定した文脈を渡す方法。
Claude Code Revenue CTA Routing: 記事からPDF、Gumroad、相談へ送る設計
PVだけで終わらせず、読者の状態に合わせて無料PDF、Gumroad教材、導入相談へ分岐するCTA設計です。
Claude Codeチーム引き継ぎルール: レビュー、権限、収益導線まで渡す実務手順
Claude Codeの作業をチームで渡すための証拠、権限、ロールバック、無料PDF/Gumroad/相談導線の実務ルール。