Claude Code × AWS CodePipeline/CodeBuild 완전 가이드 | CI/CD 파이프라인 자동 구축
Claude Code로 AWS CodePipeline·CodeBuild CI/CD를 자동 구축. 파이프라인 설계·buildspec.yml 생성·테스트 자동화·CDK 인프라 정의까지 실전 코드로 해설.
“GitHub Actions로 충분한데 왜 굳이 AWS CodePipeline을 써야 해?”—자주 받는 질문입니다.
답은 AWS 리소스와의 깊은 통합에 있습니다. ECR 푸시, ECS 배포, CloudFormation 스택 업데이트—이 모든 것을 AWS 네이티브로 완결하고 싶을 때 CodePipeline + CodeBuild 조합이 가장 원활합니다.
저는 업무에서 여러 AWS 서비스를 조합한 파이프라인을 관리하는데, Claude Code에 파이프라인 요건을 전달하기만 하면 buildspec.yml·CDK 코드·IAM 정책이 한꺼번에 생성되기 시작한 이후로 신규 파이프라인 구축 시간이 1/4로 줄었습니다.
CodePipeline / CodeBuild 기본 구조
CodePipeline (오케스트레이터)
│
├─ Source 스테이지: GitHub / CodeCommit에서 코드 취득
├─ Build 스테이지: CodeBuild로 빌드·테스트·Docker 이미지 생성
├─ Test 스테이지: 통합 테스트·보안 스캔 (옵션)
└─ Deploy 스테이지: ECS / Elastic Beanstalk / S3에 배포
CodeBuild는 buildspec.yml에 기술한 명령을 실행합니다. GitHub Actions의 steps:에 해당하는 것으로 이해하면 쉽습니다.
Step 1: buildspec.yml 자동 생성
claude -p "
다음 조건으로 CodeBuild의 buildspec.yml을 생성해.
【빌드 내용】
- Node.js 20 환경
- npm ci로 설치
- TypeScript 빌드 (npm run build)
- 유닛 테스트 실행 (npm test)
- Docker 이미지 빌드 후 ECR에 푸시
- 이미지 태그: CODEBUILD_RESOLVED_SOURCE_VERSION (Git SHA)
- latest 태그도 동시에 부여
【보안 스캔】
- ECR 이미지 푸시 후 Trivy로 스캔
- HIGH/CRITICAL 취약점 있으면 빌드 실패
【아티팩트】
- imagedefinitions.json 출력 (ECS 배포용)
"
생성되는 buildspec.yml:
version: 0.2
env:
variables:
AWS_DEFAULT_REGION: ap-northeast-2
ECR_REPO_NAME: myapp
parameter-store:
ECR_REGISTRY: /myapp/ecr-registry
phases:
install:
runtime-versions:
nodejs: 20
commands:
- echo "의존성 설치 중..."
- npm ci
pre_build:
commands:
- echo "테스트 실행 중..."
- npm test
- echo "Amazon ECR에 로그인 중..."
- aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
- IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
- IMAGE_URI=$ECR_REGISTRY/$ECR_REPO_NAME:$IMAGE_TAG
build:
commands:
- echo "TypeScript 빌드 중..."
- npm run build
- echo "Docker 이미지 빌드 중..."
- docker build -t $IMAGE_URI -t $ECR_REGISTRY/$ECR_REPO_NAME:latest .
post_build:
commands:
- echo "ECR에 이미지 푸시 중..."
- docker push $IMAGE_URI
- docker push $ECR_REGISTRY/$ECR_REPO_NAME:latest
- echo "이미지 취약점 스캔 중..."
- |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image \
--exit-code 1 \
--severity HIGH,CRITICAL \
$IMAGE_URI
- echo "imagedefinitions.json 생성 중..."
- printf '[{"name":"app","imageUri":"%s"}]' $IMAGE_URI > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
reports:
test-reports:
files:
- "coverage/junit.xml"
file-format: JUNITXML
Step 2: CDK로 파이프라인 전체 구축
claude -p "
lib/pipeline-stack.ts에 다음 CodePipeline을 CDK TypeScript로 구현해.
【파이프라인 구성】
- Source: GitHub (owner/repo의 main 브랜치)
- Build: CodeBuild (위의 buildspec.yml 사용)
- Deploy: ECS 서비스에 Blue/Green 배포
【알림】
- 파이프라인 실패 시 SNS → Slack으로 알림
- 배포 성공 시에도 Slack으로 알림
【아티팩트 스토어】
- S3 버킷 (암호화·버전 관리 활성화)
"
// lib/pipeline-stack.ts
import * as cdk from "aws-cdk-lib";
import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import * as codepipeline_actions from "aws-cdk-lib/aws-codepipeline-actions";
import * as codebuild from "aws-cdk-lib/aws-codebuild";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";
import * as sns from "aws-cdk-lib/aws-sns";
export class PipelineStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 아티팩트 스토어 S3
const artifactBucket = new s3.Bucket(this, "ArtifactBucket", {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// 아티팩트 정의
const sourceOutput = new codepipeline.Artifact("SourceOutput");
const buildOutput = new codepipeline.Artifact("BuildOutput");
// CodeBuild 프로젝트
const buildProject = new codebuild.PipelineProject(this, "BuildProject", {
buildSpec: codebuild.BuildSpec.fromSourceFilename("buildspec.yml"),
environment: {
buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
privileged: true, // Docker 빌드에 필수
},
environmentVariables: {
AWS_ACCOUNT_ID: { value: this.account },
},
});
// ECR 접근 권한 부여
buildProject.addToRolePolicy(new iam.PolicyStatement({
actions: [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
],
resources: ["*"],
}));
// 파이프라인
const pipeline = new codepipeline.Pipeline(this, "Pipeline", {
pipelineName: "myapp-pipeline",
artifactBucket,
stages: [
{
stageName: "Source",
actions: [
new codepipeline_actions.GitHubSourceAction({
actionName: "GitHub_Source",
owner: "your-org",
repo: "your-repo",
branch: "main",
oauthToken: cdk.SecretValue.secretsManager("github-token"),
output: sourceOutput,
}),
],
},
{
stageName: "Build",
actions: [
new codepipeline_actions.CodeBuildAction({
actionName: "Build_and_Test",
project: buildProject,
input: sourceOutput,
outputs: [buildOutput],
}),
],
},
{
stageName: "Deploy",
actions: [
new codepipeline_actions.EcsDeployAction({
actionName: "Deploy_to_ECS",
service: ecs.FargateService.fromFargateServiceAttributes(
this, "EcsService", {
cluster: ecs.Cluster.fromClusterArn(
this, "Cluster",
`arn:aws:ecs:${this.region}:${this.account}:cluster/myapp-cluster`
),
serviceName: "myapp-service",
}
),
input: buildOutput,
}),
],
},
],
});
// 실패 알림
const alertTopic = new sns.Topic(this, "AlertTopic");
pipeline.notifyOnAnyStageStateChange("PipelineNotification", alertTopic, {
events: [
codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_FAILED,
codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_SUCCEEDED,
],
});
}
}
Step 3: 테스트 결과 리포트 설정
claude -p "
CodeBuild에서 테스트 결과를 CodeBuild Reports에 전송해
PR마다 품질 리포트를 확인할 수 있도록 하고 싶어.
- 테스트 프레임워크: Vitest
- 커버리지 리포트: Istanbul (lcov 형식)
- buildspec.yml에 reports 섹션 추가
- CDK로 리포트 그룹도 정의
"
# buildspec.yml의 reports 섹션
reports:
UnitTestResults:
files:
- "test-results/junit.xml"
file-format: JUNITXML
CodeCoverage:
files:
- "coverage/lcov.info"
file-format: CLOVERXML
Step 4: 멀티 환경 파이프라인 설계
claude -p "
dev → staging → prod 3개 환경으로의 단계 배포 파이프라인을 CDK로 설계해.
- dev: main 브랜치에 push하면 자동 배포
- staging: dev 배포 성공 후, 수동 승인 후 배포
- prod: staging 배포 성공 후, 수동 승인 후 배포
- 각 환경 배포 완료를 Slack에 알림
"
// staging → prod 수동 승인 게이트 추가
{
stageName: "Approve_Staging",
actions: [
new codepipeline_actions.ManualApprovalAction({
actionName: "Approve_Deploy_to_Staging",
notificationTopic: alertTopic,
additionalInformation: "Staging 배포를 승인하시겠습니까?",
}),
],
},
{
stageName: "Deploy_Staging",
actions: [
new codepipeline_actions.EcsDeployAction({
actionName: "Deploy_to_Staging",
service: stagingService,
input: buildOutput,
}),
],
},
주의할 함정 4가지
1. CodeBuild의 privileged: true를 잊는 경우
Docker 이미지를 빌드하려면 privileged: true가 필수입니다. 없으면 Cannot connect to the Docker daemon 에러가 납니다.
2. GitHub OAuth 토큰 권한 부족
GitHub 소스에는 repo 스코프가 필요합니다. public_repo만으로는 프라이빗 리포지토리에 사용할 수 없습니다.
3. S3 아티팩트 버킷 리전
파이프라인과 아티팩트 S3 버킷은 같은 리전이어야 합니다. 크로스 리전 파이프라인은 별도 설정이 필요합니다.
4. ECS 배포 액션의 imagedefinitions.json 형식
ECS 배포에는 정확한 형식이 필요합니다:
[{"name": "컨테이너명", "imageUri": "이미지URI"}]
컨테이너 이름은 태스크 정의의 컨테이너 이름과 완전히 일치해야 합니다.
정리
| 태스크 | Claude Code의 기여 |
|---|---|
| buildspec.yml 생성 | 빌드·테스트·Docker·보안 스캔 포함해서 생성 |
| CDK 파이프라인 | Source→Build→Deploy 전 스테이지 자동 생성 |
| 멀티 환경 설계 | 수동 승인 게이트 포함한 단계 배포 설계 |
| 테스트 리포트 | CodeBuild Reports 설정 자동화 |
CodePipeline 설정은 복잡해 보이지만, Claude Code에 “이런 파이프라인이 필요해”라고 전달하기만 하면 buildspec.yml도 CDK 코드도 한꺼번에 갖춰집니다. 먼저 buildspec.yml부터 시도해 보세요.
관련 기사
- Claude Code × AWS ECS/Fargate 완전 가이드
- Claude Code × AWS CloudFormation/CDK 완전 가이드
- Claude Code × AWS IAM 완전 가이드
참고 자료
Claude Code 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
무료 PDF: 5분 완성 Claude Code 치트시트
이메일 주소만 등록하시면 A4 한 장짜리 치트시트 PDF를 즉시 보내드립니다.
개인정보는 엄격하게 관리하며 스팸은 보내지 않습니다.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code × Amazon Bedrock 완전 가이드 | AWS에서 Claude 프로덕션 운영하기
Claude Code로 Amazon Bedrock을 활용하는 완전 가이드. IAM 인증, 스트리밍, Lambda 통합, RAG 구현, 비용 최적화까지 — Masa의 실제 프로덕션 구현 경험을 바탕으로 해설.
Claude Code × AWS CloudWatch 완벽 가이드 | 로그 분석·알람 설정·대시보드 자동 구축
Claude Code로 AWS CloudWatch를 효율화하세요. 로그 패턴 분석·알람 자동 설정·메트릭 대시보드 구축·인시던트 조사까지 실전 코드로 해설합니다.
Claude Code × AWS ECS/Fargate 완전 가이드 | 컨테이너 배포 자동화하기
Claude Code로 AWS ECS/Fargate 배포를 자동화하세요. 태스크 정의부터 서비스 설정, Blue/Green 배포, CDK 인프라 구축까지 — Masa의 실무 경험을 바탕으로 해설합니다.