Use Cases (更新: 2026/6/3)

Claude CodeでAWS CloudFormation/CDKを安全に使う実践ガイド

Claude CodeでAWS CDK/CloudFormationを安全にレビューし、差分・IAM・ドリフト・ロールバックまで実践解説。

Claude CodeでAWS CloudFormation/CDKを安全に使う実践ガイド

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公式ドキュメントを前提にしています。特に次の公式情報を基準にしました。

Claude Codeに任せる範囲を決める

最初に決めるべきなのは、Claude Codeに何をさせ、何をさせないかです。おすすめは次の分担です。

作業Claude Codeに任せる人間が確認する
要件整理リソース一覧、環境差分、依存関係の整理本当に必要なリソースか
テンプレート作成CloudFormation/CDKの初稿命名、削除保護、課金影響
IAM設計必要アクションの候補出しResourceConditionが狭いか
差分レビュー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

この段階で見るべき単語は、AddModifyRemoveReplacementです。特に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ではありません。synthdiffです。

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ポリシーのActionResource、Security Groupの0.0.0.0/0、RDSやDynamoDBの削除保護、S3の公開設定、CloudFrontやNAT Gatewayの追加です。NAT Gatewayは検証環境でも固定費が出やすく、Claude Codeに「この構成の月額コストが増える可能性を列挙して」と聞く価値があります。

ユースケース4: ロールバックとドリフト調査を標準化する

デプロイが失敗したときに、あわててコンソールで直すとドリフトが起きます。CloudFormationのロールバック状態、UPDATE_ROLLBACK_FAILEDROLLBACK_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.DESTROYRETAINstageで切り替えます。ただし、検証環境で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 synthnpx cdk diff、CloudFormationならchange setとdrift detectionを使い、Claude Codeには危険な変更を説明させる。この流れを守るだけで、IaCの導入はかなり安全になります。

実際に試した結果、Claude Codeに「作って」とだけ頼んだ時より、「最小権限、削除保護、コスト、ロールバック、ドリフトの観点でレビューして」と頼んだ時の方が、本番前に役立つ指摘が明らかに増えました。小さなS3とIAMロールの例でも、change setで置換や削除を確認し、diffを説明させる流れを入れるだけで、レビュー会話が具体的になります。AIはデプロイ担当ではなく、厳しい二人目のレビュアーとして使うのが一番実務的です。

#claude-code #aws #cloudformation #cdk #iac #typescript
無料

無料PDF: Claude Code はじめてのチートシート

まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。

スパムは送りません。登録情報は厳重に管理します。

Claude Codeを仕事で使える形にしませんか?

無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。

Masa

この記事を書いた人

Masa

Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。

PR

関連書籍・参考図書

この記事のテーマに関連する書籍を楽天ブックスで探せます。

※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。