v AWS CDK 2 개발자 안내서입니다. 이전 CDK v1은 2022년 6월 1일에 유지 관리에 들어갔으며 2023년 6월 1일에 지원이 종료되었습니다.
기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
AWS Construct Library의 CDK Pipelines 모듈을 사용하여 AWS CDK 애플리케이션의 지속적 전송을 구성합니다. CDK 앱의 소스 코드를 AWS CodeCommit또는에 커밋하면 GitHub AWS CodeStar CDK Pipelines에서 새 버전을 자동으로 빌드, 테스트 및 배포할 수 있습니다.
CDK Pipelines는 자체 업데이트 중입니다. 애플리케이션 스테이지 또는 스택을 추가하면 파이프라인은 자동으로 재구성되어 새 스테이지 또는 스택을 배포합니다.
참고
CDK Pipelines는 2개의 API를 지원합니다. 하나는 CDK Pipelines 개발자 미리 보기에서 제공된 원래 API입니다. 다른 하나는 미리 보기 단계에서 받은 CDK 고객의 피드백을 통합하는 최신 API입니다. 이 주제의 예에서는 최신 API를 사용합니다. 지원되는 두 API 간의 차이점에 대한 자세한 내용은 aws-cdk GitHub 리포지토리의 CDK Pipelines original API
AWS 환경 부트스트랩
CDK Pipelines을 사용하려면 먼저 스택을 배포할 AWS 환경을 부트스트랩해야 합니다.
CDK Pipeline에는 2개 이상의 환경이 포함됩니다. 첫 번째 환경은 파이프라인이 프로비저닝되는 곳입니다. 두 번째 환경은 애플리케이션의 스택 또는 스테이지를 배포하려는 곳입니다(스테이지는 관련 스택의 그룹임). 이러한 환경은 동일할 수 있지만 다양한 환경에서 스테이지를 서로 격리하는 것이 가장 좋습니다.
참고
부트스트랩으로 생성된 리소스의 종류와 부트스트랩 스택을 사용자 지정하는 방법에 대한 자세한 내용은 AWS CDK 부트스트래핑 섹션을 참조하세요.
CDK Pipelines를 사용하여 지속적으로 배포하려면 CDK Toolkit 스택에 다음이 포함되어야 합니다.
-
Amazon Simple Storage Service(S3) 버킷
-
Amazon ECR 리포지토리
-
파이프라인의 다양한 부분에 필요한 권한을 부여하는 IAM 역할입니다.
CDK Toolkit는 기존 부트스트랩 스택을 업그레이드하거나 필요한 경우 새 부트스트랩 스택을 생성합니다.
AWS CDK 파이프라인을 프로비저닝할 수 있는 환경을 부트스트랩하려면 다음 예제와 cdk bootstrap
같이를 호출합니다. npx
명령을 통해 AWS CDK Toolkit을 호출하면 필요한 경우 일시적으로 설치됩니다. 또한 현재 프로젝트에 설치된 Toolkit 버전이 있는 경우 해당 버전이 사용됩니다.
--cloudformation-execution-policies
는 향후 CDK Pipelines 배포가 실행될 정책의 ARN을 지정합니다. 기본 AdministratorAccess
정책은 파이프라인이 모든 유형의 AWS 리소스를 배포할 수 있도록 합니다. 이 정책을 사용하는 경우 AWS CDK 앱을 구성하는 모든 코드와 종속성을 신뢰해야 합니다.
대부분의 조직에서는 자동화를 통해 어떤 종류의 리소스를 배포할 수 있는지에 대해 더 엄격한 제어를 요구합니다. 조직 내 해당 부서에 문의하여 파이프라인에서 사용해야 하는 정책을 결정합니다.
기본 AWS 프로필에 필요한 인증 구성 및가 포함된 경우 --profile
옵션을 생략할 수 있습니다 AWS 리전.
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-PROFILE
\ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
파이프라인에서 AWS CDK 애플리케이션을 배포할 추가 환경을 부트스트랩하려면 대신 다음 명령을 사용합니다. --trust
옵션은이 환경에 AWS CDK 애플리케이션을 배포할 수 있는 권한이 있어야 하는 다른 계정을 나타냅니다. 이 옵션에서 파이프라인의 AWS 계정 ID를 지정합니다.
기본 AWS 프로필에 필요한 인증 구성 및가 포함된 경우 --profile
옵션을 생략할 수 있습니다 AWS 리전.
npx cdk bootstrap aws://
ACCOUNT-NUMBER
/REGION
--profileADMIN-PROFILE
\ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ --trustPIPELINE-ACCOUNT-NUMBER
작은 정보
초기 파이프라인을 부트스트래핑하고 프로비저닝할 때만 관리 자격 증명을 사용하세요. 그런 다음 로컬 시스템이 아닌 파이프라인 자체를 사용하여 변경 사항을 배포하세요.
레거시 부트스트랩 환경을 업그레이드하는 경우 새 버킷이 생성될 때 이전 Amazon S3 버킷이 고립됩니다. Amazon S3 콘솔을 사용하여 해당 버킷을 수동으로 삭제합니다.
부트스트랩 스택이 삭제되지 않도록 보호
부트스트랩 스택이 삭제되면 CDK 배포를 지원하기 위해 환경에서 원래 프로비저닝된 AWS 리소스도 삭제됩니다. 이로 인해 파이프라인이 작동을 멈추게 됩니다. 이 경우 복구를 위한 일반적인 해결책은 없습니다.
환경이 부트스트래핑된 후에는 환경의 부트스트랩 스택을 삭제하고 다시 생성하지 마세요. 대신 cdk bootstrap
명령을 다시 실행하여 부트스트랩 스택을 새 버전으로 업데이트해 보세요.
부트스트랩 스택이 실수로 삭제되지 않도록 보호하려면 cdk bootstrap
명령과 함께 --termination-protection
옵션을 제공하여 종료 방지를 활성화하는 것이 좋습니다. 신규 또는 기존 부트스트랩 스택에서 종료 방지를 활성화할 수 있습니다. 이 옵션에 대해 자세히 알아보려면 --termination-protection
섹션을 참조하세요.
종료 방지를 활성화한 후 AWS CLI 또는 CloudFormation 콘솔을 사용하여 확인할 수 있습니다.
종료 방지 기능을 활성화하려면 다음을 수행하세요.
-
다음 명령을 실행하여 새 부트스트랩 스택이나 기존 부트스트랩 스택에서 종료 방지를 활성화합니다.
$
cdk bootstrap --termination-protection
-
AWS CLI 또는 CloudFormation 콘솔을 사용하여 확인합니다. 다음은 AWS CLI사용을 보여 주는 예제입니다. 부트스트랩 스택 이름을 수정한 경우
CDKToolkit
를 스택 이름으로 바꿉니다.$
aws cloudformation describe-stacks --stack-name
" trueCDKToolkit
--query "Stacks[0].EnableTerminationProtection
프로젝트 초기화
빈 GitHub 프로젝트를 새로 생성하고 my-pipeline
디렉터리의 워크스테이션에 복제합니다. (이 주제의 코드 예제에서는 GitHub를 사용합니다. 또는를 사용할 AWS CodeStar 수도 있습니다 AWS CodeCommit.)
git clone
GITHUB-CLONE-URL
my-pipeline cd my-pipeline
참고
앱의 기본 디렉터리에 my-pipeline
이외의 이름을 사용할 수 있습니다. 그러나 이렇게 하면 이 주제의 뒷부분에서 파일 및 클래스 이름을 수정해야 합니다. 이는 AWS CDK Toolkit이 기본 디렉터리의 이름을 기반으로 일부 파일 및 클래스 이름을 설정하기 때문입니다.
복제한 후 평소와 같이 프로젝트를 초기화합니다.
$
cdk init app --language typescript
중요
cdk.json
및 cdk.context.json
파일을 소스 제어에 커밋해야 합니다. 컨텍스트 정보(예: AWS 계정에서 검색된 기능 플래그 및 캐시된 값)는 프로젝트 상태의 일부입니다. 값은 다른 환경에서 다를 수 있으며, 이로 인해 결과에 예상치 못한 변화가 발생할 수 있습니다. 자세한 내용은 컨텍스트 값 및 AWS CDK 단원을 참조하십시오.
파이프라인 정의
CDK Pipelines 애플리케이션에는 파이프라인 자체를 나타내는 스택과 이를 통해 배포된 애플리케이션을 나타내는 하나 이상의 스택이 포함됩니다. 스택은 여러 환경에 인프라 스택의 사본을 배포하는 데 사용할 수 있는 스테이지로 그룹화할 수도 있습니다. 지금은 파이프라인을 고려하고 나중에 배포할 애플리케이션을 자세히 살펴보겠습니다.
구문CodePipeline
은를 배포 엔진 AWS CodePipeline 으로 사용하는 CDK 파이프라인을 나타내는 구문입니다. 스택에서 CodePipeline
을 인스턴스화할 때 파이프라인(예: GitHub 리포지토리)의 소스 위치를 정의합니다. 앱을 빌드하는 명령도 정의합니다.
예를 들어, 다음은 소스가 GitHub 리포지토리에 저장되는 파이프라인을 정의합니다. 또한 TypeScript CDK 애플리케이션의 빌드 단계도 포함되어 있습니다. 표시된 곳에 GitHub 리포지토리에 대한 정보를 입력합니다.
참고
기본적으로 파이프라인은 Secrets Manager에 github-token
이라는 이름으로 저장된 개인 액세스 토큰을 사용하여 GitHub에 인증합니다.
또한 파이프라인 스택의 인스턴스화를 업데이트하여 AWS 계정과 리전을 지정해야 합니다.
lib/my-pipeline-stack.ts
(프로젝트 폴더 이름이 my-pipeline
이 아닌 경우 다를 수 있음):
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
}
}
bin/my-pipeline.ts
(프로젝트 폴더 이름이 my-pipeline
이 아닌 경우 다를 수 있음):
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { MyPipelineStack } from '../lib/my-pipeline-stack';
const app = new cdk.App();
new MyPipelineStack(app, 'MyPipelineStack', {
env: {
account: '111111111111
',
region: 'eu-west-1
',
}
});
app.synth();
파이프라인을 한 번 수동으로 배포해야 합니다. 그런 다음 파이프라인은 소스 코드 리포지토리에서 최신 상태를 유지합니다. 따라서 리포지토리의 코드가 배포하려는 코드인지 확인합니다. 변경 사항을 체크인하고 GitHub에 푸시한 다음 배포합니다.
git add --all git commit -m "initial commit" git push cdk deploy
작은 정보
이제 초기 배포를 완료했으므로 로컬 AWS 계정에 더 이상 관리 액세스 권한이 필요하지 않습니다. 이는 앱의 모든 변경 사항이 파이프라인을 통해 배포되기 때문입니다. GitHub로 푸시하기만 하면 됩니다.
애플리케이션 스테이지
파이프라인에 한 번에 모두 추가할 수 있는 다중 스택 AWS 애플리케이션을 정의하려면의 하위 클래스를 정의합니다Stage
. 이는 CDK Pipelines 모듈의 CdkStage
와 다릅니다.
스테이지에는 애플리케이션을 구성하는 스택이 포함되어 있습니다. 스택 간에 종속성이 있는 경우 스택은 올바른 순서로 파이프라인에 자동으로 추가됩니다. 서로 의존하지 않는 스택은 병렬로 배포됩니다. stack1.addDependency(stack2)
를 직접적으로 호출하여 스택 간에 종속 관계를 추가할 수 있습니다.
스테이지는 기본 env
인수를 수락하며, 이는 그 안에 있는 스택의 기본 환경이 됩니다. 스택은 여전히 자체 환경을 지정할 수 있습니다.
Stage
의 인스턴스를 사용하여 addStage()
를 직접적으로 호출하면 애플리케이션이 파이프라인에 추가됩니다. 스테이지를 여러 번 인스턴스화하고 파이프라인에 추가하여 DTAP 또는 다중 리전 애플리케이션 파이프라인의 서로 다른 스테이지를 정의할 수 있습니다.
간단한 Lambda 함수가 포함된 스택이 생성되고 스테이지에 배치됩니다. 그런 다음 배포할 수 있도록 파이프라인에 스테이지가 추가됩니다.
Lambda 함수가 포함된 애플리케이션 스택을 보관할 새 파일 lib/my-pipeline-lambda-stack.ts
를 생성합니다.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Function, InlineCode, Runtime } from 'aws-cdk-lib/aws-lambda';
export class MyLambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new Function(this, 'LambdaFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: new InlineCode('exports.handler = _ => "Hello, CDK";')
});
}
}
스테이지를 보관할 새 파일 lib/my-pipeline-app-stage.ts
를 생성합니다.
import * as cdk from 'aws-cdk-lib';
import { Construct } from "constructs";
import { MyLambdaStack } from './my-pipeline-lambda-stack';
export class MyPipelineAppStage extends cdk.Stage {
constructor(scope: Construct, id: string, props?: cdk.StageProps) {
super(scope, id, props);
const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
}
}
lib/my-pipeline-stack.ts
를 편집하여 파이프라인에 스테이지를 추가합니다.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
import { MyPipelineAppStage } from './my-pipeline-app-stage';
export class MyPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
pipeline.addStage(new MyPipelineAppStage(this, "test", {
env: { account: "111111111111
", region: "eu-west-1
" }
}));
}
}
addStage()
로 추가된 모든 애플리케이션 스테이지는 addStage()
직접 호출에 의해 반환된 StageDeployment 인스턴스로 표현되는 해당 파이프라인 단계의 추가를 초래합니다. addPre()
또는 addPost()
메서드를 직접적으로 호출하여 스테이지에 배포 전 또는 배포 후 작업을 추가할 수 있습니다.
// import { ManualApprovalStep } from 'aws-cdk-lib/pipelines';
const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
testingStage.addPost(new ManualApprovalStep('approval'));
Wave에 스테이지를 추가하여 여러 계정 또는 리전에 스테이지를 배포할 때와 같이 병렬로 배포할 수 있습니다.
const wave = pipeline.addWave('wave');
wave.addStage(new MyApplicationStage(this, 'MyAppEU', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
wave.addStage(new MyApplicationStage(this, 'MyAppUS', {
env: { account: '111111111111
', region: 'us-west-1
' }
}));
배포 테스트
CDK Pipelines에 단계를 추가하여 수행 중인 배포를 검증할 수 있습니다. 예를 들어 CDK Pipelines 라이브러리의 ShellStep
을 사용하여 다음과 같은 태스크를 수행할 수 있습니다.
-
Lambda 함수가 지원하는 새로 배포된 Amazon API Gateway에 액세스하려고 시도
-
AWS CLI 명령을 실행하여 배포된 리소스의 설정 확인
다음은 가장 간단한 형식의 검증 작업 추가 방법입니다.
// stage was returned by pipeline.addStage
stage.addPost(new ShellStep("validate", {
commands: ['../tests/validate.sh'],
}));
많은 AWS CloudFormation 배포로 인해 예측할 수 없는 이름의 리소스가 생성됩니다. 따라서 CDK Pipelines은 배포 후 AWS CloudFormation 출력을 읽을 수 있는 방법을 제공합니다. 예를 들어, 이를 통해 로드 밸런서의 생성된 URL을 테스트 작업에 전달하는 것이 가능해집니다.
출력을 사용하려면 관심 있는 CfnOutput
객체를 노출합니다. 그런 다음 이를 단계의 envFromCfnOutputs
속성에 전달하여 해당 단계에서 환경 변수로 사용할 수 있도록 합니다.
// given a stack lbStack that exposes a load balancer construct as loadBalancer
this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', {
value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/`
});
// pass the load balancer address to a shell step
stage.addPost(new ShellStep("lbaddr", {
envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress},
commands: ['echo $lb_addr']
}));
ShellStep
에서 바로 간단한 검증 테스트를 작성할 수 있지만 테스트가 몇 줄 이상일 때는 이 접근 방식은 다루기 어려워집니다. 보다 복잡한 테스트의 경우 inputs
속성을 통해 추가 파일(예: 전체 쉘 스크립트 또는 다른 언어의 프로그램)을 ShellStep
으로 가져올 수 있습니다. 입력은 소스(예: GitHub 리포지토리) 또는 다른 ShellStep
을 포함하여 출력이 있는 모든 단계일 수 있습니다.
소스 리포지토리에서 파일을 가져오는 것은 파일이 테스트에서 직접 사용 가능한 경우(예: 파일 자체가 실행 가능한 경우) 적합합니다. 이 예에서는 CodePipeline
의 일부로 인라인 인스턴스화하지 않고 GitHub 리포지토리를 source
로 선언합니다. 그런 다음 이 파일 세트를 파이프라인과 검증 테스트 모두에 전달합니다.
const source = CodePipelineSource.gitHub('OWNER
/REPO
', 'main');
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: new ShellStep('Synth', {
input: source,
commands: ['npm ci', 'npm run build', 'npx cdk synth']
})
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
stage.addPost(new ShellStep('validate', {
input: source,
commands: ['sh ../tests/validate.sh']
}));
테스트를 컴파일해야 하는 경우 합성 단계에서 추가 파일을 가져오는 것이 적절하며, 이는 합성의 일부로 수행됩니다.
const synthStep = new ShellStep('Synth', {
input: CodePipelineSource.gitHub('OWNER
/REPO
', 'main'),
commands: ['npm ci', 'npm run build', 'npx cdk synth'],
});
const pipeline = new CodePipeline(this, 'Pipeline', {
pipelineName: 'MyPipeline',
synth: synthStep
});
const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', {
env: { account: '111111111111
', region: 'eu-west-1
' }
}));
// run a script that was transpiled from TypeScript during synthesis
stage.addPost(new ShellStep('validate', {
input: synthStep,
commands: ['node tests/validate.js']
}));
보안 참고 사항
모든 형태의 지속적 전송에는 내재된 보안 위험이 있습니다. AWS 공동 책임 모델에서
그러나 그 특성상 의도한 목적을 이행하기 위해 높은 수준의 액세스가 필요한 라이브러리는 완전한 보안을 보장할 수 없습니다. AWS 및 조직 외부에는 많은 공격 벡터가 있습니다.
특히 다음 사항에 유의하세요.
-
의존하는 소프트웨어에 유의합니다. 배포되는 인프라를 변경할 수 있으므로 파이프라인에서 실행하는 모든 타사 소프트웨어를 검증합니다.
-
종속성 잠금을 사용하여 실수로 인한 업그레이드를 방지합니다. CDK Pipelines는
package-lock.json
및yarn.lock
을 준수하여 종속성이 예상한 대로인지 확인합니다. -
CDK Pipelines는 자체 계정에서 생성된 리소스에서 실행되며, 이러한 리소스의 구성은 파이프라인을 통해 코드를 제출하는 개발자에 의해 제어됩니다. 따라서 CDK Pipelines는 자체적으로 규정 준수 검사를 우회하려는 악의적인 개발자로부터 보호할 수 없습니다. 위협 모델에 CDK 코드를 작성하는 개발자가 포함된 경우 AWS CloudFormation 실행 역할에 비활성화할 권한이 없는 AWS CloudFormation 후크
(예방) 또는 AWS Config (대응)와 같은 외부 규정 준수 메커니즘이 있어야 합니다. -
프로덕션 환경에 대한 자격 증명은 수명이 짧아야 합니다. 부트스트래핑 및 초기 프로비저닝 후에는 개발자가 계정 자격 증명을 보유할 필요가 전혀 없습니다. 변경 사항은 파이프라인을 통해 배포할 수 있습니다. 애초에 자격 증명이 필요하지 않도록 하여 자격 증명 유출 가능성을 줄입니다.
문제 해결
CDK Pipelines를 시작하는 동안 일반적으로 다음과 같은 문제가 발생합니다.
- 파이프라인: 내부 실패
-
CREATE_FAILED | AWS::CodePipeline::Pipeline | Pipeline/Pipeline Internal Failure
GitHub 액세스 토큰을 확인합니다. 누락되었거나 리포지토리에 액세스할 권한이 없을 수 있습니다.
- 키: 정책에 하나 이상의 유효하지 않은 위탁자가 있는 문이 포함되어 있습니다.
-
CREATE_FAILED | AWS::KMS::Key | Pipeline/Pipeline/ArtifactsBucketEncryptionKey Policy contains a statement with one or more invalid principals.
대상 환경 중 하나가 새 부트스트랩 스택으로 부트스트래핑되지 않았습니다. 모든 대상 환경이 부트스트래핑되었는지 확인합니다.
- 스택이 ROLLBACK_COMPLETE 상태이므로 업데이트할 수 없습니다.
-
Stack
STACK_NAME
is in ROLLBACK_COMPLETE state and can not be updated. (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: ...)스택이 이전 배포에 실패했으며 재시도할 수 없는 상태입니다. AWS CloudFormation 콘솔에서 스택을 삭제하고 배포를 다시 시도합니다.