Use Cases (업데이트: 2026. 6. 3.)

Claude Code로 AWS CloudFormation/CDK를 안전하게 리뷰하는 실전 가이드

Claude Code로 AWS CDK와 CloudFormation을 안전하게 검토하고 IAM, diff, 드리프트, 롤백을 다룹니다.

Claude Code로 AWS CloudFormation/CDK를 안전하게 리뷰하는 실전 가이드

AWS Console에서 클릭 몇 번으로 인프라를 바꾸는 것은 빠릅니다. 하지만 시간이 지나면 “왜 운영 환경만 이 값인가”, “staging과 무엇이 다른가”를 설명하기 어려워집니다. CloudFormation과 AWS CDK는 인프라를 코드로 남기는 방법이지만, 코드라고 해서 자동으로 안전해지는 것은 아닙니다. 넓은 IAM 권한, 의도치 않은 리소스 교체, 방치된 NAT Gateway는 보안과 비용 사고로 이어집니다.

Claude Code는 여기서 유용합니다. 다만 자동 배포 담당자로 두면 위험합니다. 저는 Claude Code를 CloudFormation/CDK 초안을 만들고, cdk diff를 설명하고, IAM 권한 확대를 찾아내고, CloudFormation 이벤트를 롤백 체크리스트로 정리하는 리뷰 파트너로 사용합니다. 승인 책임은 여전히 사람에게 있어야 합니다.

초보자를 위해 정리하면 CloudFormation은 AWS 공식 템플릿 실행 서비스입니다. CDK는 TypeScript 같은 언어로 인프라를 작성한 뒤 CloudFormation 템플릿으로 합성하는 개발 키트입니다. stack은 함께 배포되는 리소스 묶음이고, drift는 코드와 실제 AWS 리소스가 달라진 상태입니다.

이 글은 2026년 6월 3일 기준 AWS 공식 문서를 바탕으로 작성했습니다.

역할 경계를 먼저 정한다

안전한 흐름은 Claude Code에게 “배포해줘”가 아니라 “엄격하게 리뷰해줘”라고 요청하는 것입니다.

작업Claude Code가 돕는 부분사람이 승인할 부분
요구사항 정리리소스, 환경, 의존성 정리정말 필요한 리소스인지
템플릿 초안CloudFormation/CDK 코드이름, 삭제 정책, 비용
IAM후보 Action/Resource/Condition최소 권한 여부
차이 리뷰cdk diff나 change set 설명삭제, 교체, 권한 확대
장애 대응이벤트 분석과 수정 후보롤백 방침과 운영 반영
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와 rollback 점검 기록"]

사용 사례 1: 작은 기존 구성을 CloudFormation으로 옮기기

처음부터 전체 운영 환경을 코드화하려고 하지 마세요. 위험이 낮은 작은 단위부터 시작하는 편이 좋습니다. 다음 템플릿은 private S3 bucket과 그 bucket만 읽을 수 있는 Lambda용 IAM role을 만듭니다. 명명된 IAM role을 생성하므로 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 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는 S3, RDS, DynamoDB, KMS key, 네트워크 리소스에서 높은 위험 신호입니다.

사용 사례 2: CDK TypeScript로 최소 안전 스택 만들기

새 프로젝트라면 CDK TypeScript가 유지보수하기 쉽습니다. 타입과 파일 구조가 명확해서 Claude Code가 작성한 결과도 리뷰하기 쉽습니다. 다음 예시는 DynamoDB, S3, Lambda만 만들며 API Gateway는 제외해 범위와 비용을 줄였습니다.

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-2",
  },
});
// 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 });
  }
}

배포 전에는 반드시 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)
"

autoDeleteObjects: !isProd는 개발 환경에서는 편하지만 운영에서 켜지면 위험합니다. Claude Code가 이런 환경별 guardrail을 확인하게 만드는 것이 핵심입니다.

사용 사례 3: 운영 diff를 승인자 언어로 설명하기

작은 TypeScript 수정이 CloudFormation에서는 큰 교체가 될 수 있습니다. 승인자가 이해할 수 있게 Claude Code에게 번역시킵니다.

claude -p "
아래 cdk diff를 AWS 전문가가 아닌 제품 책임자에게 설명하듯 요약해줘.
열은 다음으로 구성해줘:
- 변경 종류
- 대상 리소스
- 사용자 영향
- 보안 영향
- 비용 영향
- 승인 전 질문

$(npx cdk diff -c stage=prod 2>&1)
"

고위험 항목은 IAM Action/Resource, 0.0.0.0/0 보안 그룹, 삭제 보호 누락, S3 공개, CloudFront나 NAT Gateway 추가, 상태 저장 리소스 교체입니다.

사용 사례 4: 롤백과 drift 점검 표준화

배포 실패 후 Console에서 급히 수정하면 drift가 생깁니다. 이벤트로 원인을 좁히고, 영구 수정은 IaC로 되돌려야 합니다.

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 -p "
이 stack이 UPDATE_ROLLBACK_FAILED 상태야.
events를 읽고 가능한 원인, 건드려도 되는 리소스, 건드리면 안 되는 리소스, AWS 공식 문서로 확인할 절차를 나눠 설명해줘.
$(aws cloudformation describe-stack-events --stack-name cclab-iac-demo-dev 2>&1)
"

흔한 함정

IAM이 너무 넓다. 실행된다는 이유로 Action: "*" 또는 Resource: "*"를 받아들이면 안 됩니다. 실제 유스케이스에 맞춰 action, ARN, condition을 좁힙니다.

diff를 읽지 않고 deploy한다. 운영 전에는 synth, diff, change set을 확인합니다. Replacement가 보이면 멈추고 영향 범위를 확인합니다.

고정 비용을 놓친다. ALB, NAT Gateway, RDS, OpenSearch, 상시 실행 ECS는 트래픽이 낮아도 비용이 나옵니다. Claude Code에게 월 고정 비용 리소스만 따로 묻습니다.

수동 Console 변경을 영구 수정으로 둔다. 장애 중 수동 조치는 필요할 수 있지만, 이후 CloudFormation 또는 CDK에 반드시 반영해야 합니다.

secret을 코드에 쓴다. 비밀번호와 API key를 템플릿이나 Git 기록에 남기지 않습니다. Secrets Manager 또는 SSM Parameter Store를 사용하고 Claude Code가 비밀값을 출력하지 않게 합니다.

리뷰 프롬프트

당신은 엄격한 AWS CloudFormation/CDK 리뷰어입니다.
운영 배포 전 IaC diff를 검토하세요.

확인:
- IAM Action/Resource/Condition이 최소 권한인지
- security group 또는 S3가 의도치 않게 공개되는지
- 상태 저장 리소스가 삭제 또는 교체되는지
- ALB, NAT Gateway, RDS, OpenSearch 같은 월 고정 비용이 추가되는지
- CloudFormation drift 가능성이 있는지
- 롤백 시 수동 단계가 필요한 리소스가 있는지

출력:
1. 지금 수정해야 할 문제
2. 승인자에게 물을 질문
3. deploy 전 실행할 명령
4. deploy 후 실행할 명령

더 읽기

IAM을 더 깊게 다루려면 Claude Code와 AWS IAM을 읽어보세요. 컴퓨팅과 API 쪽은 AWS Lambda, AWS API Gateway, AWS DynamoDB와 함께 보면 좋습니다.

팀 리뷰 프로세스로 확장하려면 ClaudeCodeLab의 실전 제품팀 교육을 활용해 Pull Request 템플릿과 릴리스 체크리스트에 이 흐름을 넣을 수 있습니다.

정리

Claude Code와 CloudFormation/CDK의 가장 좋은 조합은 자동 배포가 아니라 엄격한 두 번째 리뷰어입니다. 초안 작성은 맡기되, 배포 전에는 IAM, 비용, 교체, 롤백, drift를 설명하게 해야 합니다. 실제로 이 흐름을 적용하면 템플릿 생성만 시켰을 때보다 cdk diff와 change set 리뷰에서 운영 위험을 더 많이 발견할 수 있습니다.

#claude-code #aws #cloudformation #cdk #iac #typescript
무료

무료 PDF: Claude Code 치트시트

이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.

개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.

Masa

작성자 소개

Masa

Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.