학습 목표
cdk synth·diff·deploy를 로컬·CI에서 안전한 순서로 실행할 수 있다.
Template assertions·snapshot test로 synth 결과를 자동 검증할 수 있다.
PR CI에서 synth·diff·test를, main에서 승인 후 deploy를 구성할 수 있다.
bootstrap·asset·stack approval이 배포 파이프라인에 미치는 영향을 설명할 수 있다.
Terraform plan file 승인 패턴과 CDK template diff 패턴을 대응시킬 수 있다.
문제 상황
cdk deploy를 로컬에서만 — PR에 template 변경이 안 보이고 리뷰 불가- construct id 바꿨더니 S3 bucket replace — 테스트 없이 프로덕션 적용
- Jest는 있는데 인프라 테스트가 없음 —
npm test통과해도 IAM 누락 - CI에서
cdk deploy만 돌림 — diff 없이 main merge = 깜짝 변경 - Lambda asset 배포 실패 — bootstrap 스택 없음
- 8편에서 synth ≈ plan은 봤지만 — 어떻게 CI에 넣는지 모름
- Terraform plan -out 승인과 CDK 무엇이 대응하는지 헷갈림
6~8편에서 App·Stack·Construct와 TF vs CDK를 봤다. 이번 편은 테스트·배포·CI — 코드가 실제 스택에 가기 전·후 게이트다. GitOps PR flow는 16편, 배포 거버넌스는 19편.
1. 로컬 워크플로 — synth · diff · deploy
배포 전 항상 synth·diff. apply/deploy는 의도 확인 후.

npm test # unit + template tests
cdk synth # cdk.out template 생성
cdk diff MyStack # deployed stack vs local template
cdk deploy MyStack # CloudFormation update
| 명령 | API 호출 | 산출물 |
|---|---|---|
| synth | 없음 (로컬) | cdk.out/*.template.json |
| diff | CFn describe + 비교 | 변경 요약 (stdout) |
| deploy | CFn create/update | stack 변경·asset upload |
| destroy | CFn delete | 리소스 삭제 |
- synth만으로 PR 검증 가능 — AWS 권한 최소화
- diff —
terraform plan에 대응 (8편) - --require-approval never — CI 전용; 로컬은 broadening 확인
- cdk.out —
.gitignore; CI artifact로 보관 가능
2. Template 테스트 — assertions와 snapshot
CDK 테스트는 런타임 앱이 아니라 synthesized template을 검증한다.

| 방식 | 검증 대상 | 적합 |
|---|---|---|
| Fine-grained assertions | 특정 resource·property | IAM·암호화·태그 정책 |
| Snapshot match | template JSON 전체 | 회귀 감지 (의도적 변경 시 갱신) |
| cdk-nag (보조) | AWS best practice rule | 보안·준수 린트 |
// code/stack.snapshot.test.ts (발췌)
import { App } from "aws-cdk-lib";
import { Template } from "aws-cdk-lib/assertions";
import { AppStack } from "../lib/app-stack";
test("S3 bucket is encrypted and blocks public access", () => {
const app = new App();
const stack = new AppStack(app, "TestStack");
const template = Template.fromStack(stack);
template.hasResourceProperties("AWS::S3::Bucket", {
BucketEncryption: {
ServerSideEncryptionConfiguration: [
{ ServerSideEncryptionByDefault: { SSEAlgorithm: "AES256" } },
],
},
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
BlockPublicPolicy: true,
},
});
});
test("snapshot matches", () => {
const app = new App();
const stack = new AppStack(app, "SnapshotStack");
expect(Template.fromStack(stack).toJSON()).toMatchSnapshot();
});
- Construct id 변경 — snapshot 전체 diff — replace 여부 확인
- Snapshot 남용 — 작은 변경도 대량 diff — assertions 우선, snapshot은 회귀용
- 여러 Stack — stack마다 test case 분리
- Python —
aws_cdk.assertions동일 패턴
3. cdk deploy — bootstrap · asset · approval
deploy는 template + asset(Lambda zip, Docker) 업로드를 한 번에 오케스트레이션한다.

| 요소 | 역할 |
|---|---|
| Bootstrap stack | asset S3 bucket·IAM (계정·리전당 1회) |
| Asset publishing | cdk.out/asset.* → bootstrap bucket |
| CloudFormation | template으로 stack create/update |
| Rollback | CFn 실패 시 이전 상태 복구 (설정에 따름) |
cdk bootstrap aws://ACCOUNT/region # 최초 1회
cdk deploy --all --require-approval broadening
- bootstrap 없으면 asset 포함 stack 실패
- broadening — IAM·보안 그룹 완화 시 승인 요구
- cross-stack reference — deploy 순서 의존 (7편 Network → App)
- hotswap (dev only) — Lambda 코드만 빠른 배포 — 프로덕션 비권장
4. CI — PR 파이프라인
PR에서는 배포하지 않고 synth·test·diff로 리뷰 재료를 만든다.

| 단계 | 명령 | 목적 |
|---|---|---|
| Install | npm ci |
lockfile 고정 |
| Lint | eslint / tsc --noEmit |
타입·스타일 |
| Test | npm test |
template assertions |
| Synth | cdk synth |
template 생성 검증 |
| Diff (선택) | cdk diff on dev |
실제 stack 대비 (credentials 필요) |
- synth in CI — 필수; AWS cred 불필요
- diff in PR — dev account read-only — 민감; 대안은 snapshot만
- PR comment — diff·snapshot summary 봇 게시
- Terraform 대응 —
terraform planartifact (8편)
# code/github-actions-pr.yaml (발췌)
jobs:
cdk-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: npm }
- run: npm ci
- run: npm run build --if-present
- run: npm test
- run: npx cdk synth
5. CI — deploy 파이프라인
main merge 후 환경별 deploy — 승인·환경 보호 필수.

| 단계 | 내용 |
|---|---|
| Trigger | merge to main · tag · manual workflow |
| Gate | staging auto → prod manual approval |
| Assume role | OIDC short-lived IAM (장기 key 금지) |
| Deploy | cdk deploy --all --require-approval never |
| Verify | smoke test · drift check (선택) |
# code/github-actions-deploy.yaml (발췌)
deploy-staging:
environment: staging
steps:
- run: npm ci && npm test && npx cdk synth
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_STAGING }}
aws-region: ap-northeast-2
- run: npx cdk deploy --all --require-approval never
deploy-prod:
needs: deploy-staging
environment: production # required reviewers
steps:
# ... same with AWS_ROLE_PROD
- Environment secrets — account·role 분리 (5편 tfvars 패턴과 유사)
- --all — App 내 모든 stack — 의존 순서 CDK가 해결
- Concurrency — 동시 deploy 취소 — stack lock 경합 방지
- 19편 — error budget·승인 거버넌스 심화
Terraform plan file과 대응
| Terraform | CDK |
|---|---|
plan -out=tfplan |
synth + snapshot / saved template |
| plan artifact 승인 | PR review + env approval |
apply tfplan |
cdk deploy (승인 후) |
6. 실무 체크리스트
| # | 질문 |
|---|---|
| 1 | PR CI에 synth·test가 있는가 |
| 2 | snapshot 변경이 리뷰에서 의도적인가 |
| 3 | prod deploy에 manual approval이 있는가 |
| 4 | CI가 OIDC로 assume role 하는가 (장기 key 없음) |
| 5 | bootstrap이 각 account·region에 있는가 |
| 6 | construct id 변경 시 replace diff를 확인했는가 |
정리
- 로컬 — test → synth → diff → deploy
- Template test — assertions(정책) + snapshot(회귀)
- deploy — bootstrap·asset·CFn; broadening 승인
- PR CI — synth·test (diff는 선택)
- deploy CI — env gate·OIDC·staging → prod
- Part 2 CDK 마무리 — 다음 Serverless Part 3
다음에 다룰 것
- Serverless 아키텍처
- FaaS, event-driven, cold start, serverless vs container
해당 내용은 AWS CDK Developer Guide (Testing), AWS CDK CLI reference 를 기반으로 합니다.
'Infrastructure as Code' 카테고리의 다른 글
| Lambda와 API Gateway (0) | 2026.07.16 |
|---|---|
| Serverless 아키텍처 (0) | 2026.07.12 |
| CDK vs Terraform (0) | 2026.07.10 |
| CDK로 인프라 정의 (0) | 2026.07.09 |
| AWS CDK 개요 (0) | 2026.07.07 |