콘텐츠로 이동

CDK Infrastructure

AWS CDK는 코드로 클라우드 인프라를 정의하고 AWS CloudFormation을 통해 프로비저닝하는 프레임워크입니다.

TypeScript 인프라 생성기는 TypeScript로 작성된 AWS CDK 인프라 애플리케이션을 생성합니다. 생성된 애플리케이션에는 Checkov 보안 검사를 통한 보안 모범 사례가 포함되어 있습니다.

두 가지 방법으로 새 인프라 프로젝트를 생성할 수 있습니다:

이 제너레이터 실행@aws/nx-plugin:ts#infra

pnpm nx g @aws/nx-plugin:ts#infra
명령 구성하기5

필수

제너레이터 옵션5 옵션
name필수string

애플리케이션의 이름입니다.

directorystring기본값: packages

새 애플리케이션의 디렉토리입니다.

subDirectorystring

프로젝트가 배치되는 하위 디렉토리입니다. 기본값은 프로젝트 이름입니다.

stageConfigboolean기본값: false

다중 환경 CDK 배포를 위한 중앙 집중식 스테이지 구성(자격 증명, 계정, 리전)을 활성화합니다.

preferInstallDependenciesboolean기본값: true

생성기 실행 후 의존성 설치를 선호할지 여부입니다. 여러 생성기를 일괄 실행할 때 설치를 연기하려면 false로 설정하세요 (후속 생성기가 Nx 프로젝트 그래프를 계산할 수 있도록 필요한 경우 설치는 여전히 실행됩니다); 마지막에 한 번만 설치합니다.

생성기는 <directory>/<name> 디렉토리에 다음과 같은 프로젝트 구조를 생성합니다:

  • 디렉터리src
    • main.ts Application entry point instantiating CDK stages to deploy
    • 디렉터리stages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • 디렉터리stacks CDK Stack definitions
      • application-stack.ts Main application stack
  • cdk.json CDK configuration
  • package.json Project manifest defining the project’s package name and dependencies
  • project.json Project configuration and build targets
  • checkov.yml Checkov configuration file

--stageConfig=true로 생성하면, 생성기는 중앙 집중식 자격 증명 관리를 위한 두 개의 공유 패키지도 생성합니다(아직 존재하지 않는 경우):

  • 디렉터리packages/common
    • 디렉터리infra-config Stage configuration types and credential mappings
      • 디렉터리src
        • stages.types.ts Type definitions for stage credentials and config
        • stages.config.ts Your stage-to-credential mappings (edit this)
        • resolve-stage.ts The resolveStage lookup your main.ts imports
        • index.ts Re-exports for importing from other packages
      • README.md
    • 디렉터리scripts Centralized deploy/destroy scripts
      • 디렉터리src
        • 디렉터리infra
          • infra-deploy.ts Deploy bin script
          • infra-destroy.ts Destroy bin script
          • index.ts Re-exports for importing from other packages
          • 디렉터리stage-credentials/ Shared logic (credential lookup, CDK command building)
      • README.md

src/stacks/application-stack.ts 내부에서 CDK 인프라 작성을 시작할 수 있습니다. 예를 들어:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Bucket } from 'aws-cdk-lib/aws-s3'
import { Construct } from 'constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Declare your infrastructure here
new Bucket(this, 'MyBucket');
}
}

CDK는 Stages를 사용하여 특정 환경에 함께 배포되어야 하는 스택을 그룹화합니다. 생성된 src/main.ts는 자체 개발 및 테스트를 위한 샌드박스 스테이지를 생성합니다:

src/main.ts
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
},
});
// Define other instances of stages, such as beta and prod, below

env 속성은 CDK에게 어떤 AWS 계정과 리전에 배포할지 알려줍니다. CDK_DEFAULT_ACCOUNTCDK_DEFAULT_REGION은 활성 AWS 자격 증명에서 CDK CLI에 의해 자동으로 해석됩니다. 자세한 내용은 CDK 환경 문서를 참조하세요.

샌드박스 스테이지는 deploy-sandboxdestroy-sandbox 타겟이 작동하는 스테이지입니다.

stageConfig로 생성한 경우, main.ts는 중앙 집중식 구성 파일에서 계정과 리전을 읽으며, 구성이 설정되지 않은 경우 환경 변수로 폴백합니다:

src/main.ts (with stageConfig)
import { resolveStage } from '@my-scope/common-infra-config';
// Looks up the stage under this project (packages/infra), falling back to
// shared stages. Returns undefined when no config exists for the stage.
const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
},
});

다른 환경에 배포하기 위해 더 많은 스테이지를 추가할 수 있습니다. 예를 들어, 별도의 AWS 계정을 대상으로 하는 betaprod 스테이지:

src/main.ts
new ApplicationStage(app, 'project-beta', {
env: {
account: '123456789012',
region: 'us-west-2',
},
});
new ApplicationStage(app, 'project-prod', {
env: {
account: '098765432109',
region: 'us-west-2',
},
});

스테이지는 하나 이상의 스택을 그룹화합니다. 스테이지 내부에 필요한 만큼 많은 스택을 추가할 수 있습니다:

src/stages/application-stage.ts
import { Stage, StageProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { BackendStack } from '../stacks/backend-stack.js';
import { FrontendStack } from '../stacks/frontend-stack.js';
export class ApplicationStage extends Stage {
constructor(scope: Construct, id: string, props?: StageProps) {
super(scope, id, props);
new BackendStack(this, 'Backend', {
crossRegionReferences: true,
})
new FrontendStack(this, 'Frontend', {
crossRegionReferences: true,
});
}
}

여러 스테이지가 서로 다른 AWS 계정을 대상으로 하는 경우, 특히 스테이지 수가 증가함에 따라 자격 증명을 수동으로 관리하는 것은 오류가 발생하기 쉽습니다.

stageConfig 옵션은 두 개의 공유 패키지를 생성하여 이 문제를 해결합니다:

  • packages/common/infra-config — 각 스테이지를 AWS 자격 증명, 계정 및 리전에 매핑하는 단일 구성 파일입니다. 이는 워크스페이스의 모든 패키지에서 가져올 수 있으므로, CDK main.ts가 동일한 신뢰할 수 있는 소스에서 계정과 리전을 읽을 수 있습니다.
  • packages/common/scripts — 자동 자격 증명 해석으로 CDK를 래핑하는 infra-deployinfra-destroy 명령입니다. deploy를 실행하면 스크립트가 구성을 읽고, CDK 자식 프로세스에 대한 올바른 AWS 환경 변수를 설정하고, cdk deploy를 실행합니다. 셸 환경은 절대 수정되지 않습니다.

packages/common/infra-config/src/stages.config.ts를 편집하여 스테이지를 AWS 자격 증명에 매핑합니다:

packages/common/infra-config/src/stages.config.ts
import type { StagesConfig } from './stages.types.js';
const config: StagesConfig = {
projects: {
// The key is the project path relative to the workspace root.
// This matches the path in project.json and in deploy commands.
'packages/infra': {
stages: {
// Stage names must match the CDK stage identifiers in main.ts
// (the first argument to `new ApplicationStage(app, 'my-app-dev', ...)`).
'my-app-dev': {
credentials: { type: 'profile', profile: 'dev-account' },
region: 'us-east-1',
},
'my-app-prod': {
credentials: {
type: 'assumeRole',
assumeRole: 'arn:aws:iam::123456789012:role/DeployRole',
},
region: 'us-west-2',
account: '123456789012',
},
},
},
},
shared: {
// Shared stages are available to all infra projects.
// Project-specific entries take priority over shared ones.
stages: {
sandbox: {
credentials: { type: 'profile', profile: 'personal-sandbox' },
region: 'us-east-1',
},
},
},
};
export default config;

예를 들어 배포할 때:

Terminal window
pnpm nx deploy infra my-app-dev/*

배포 스크립트는:

  1. 명령 인수에서 스테이지 이름 my-app-dev를 추출합니다
  2. 구성에서 자격 증명을 조회합니다: 먼저 projects['packages/infra'] 아래에서, 그 다음 shared 아래에서
  3. 찾으면 CDK 자식 프로세스에 대해서만 AWS_PROFILE을 설정합니다(또는 IAM 역할을 가정합니다)
  4. 찾지 못하면 환경에 있는 AWS 자격 증명으로 폴백합니다

이는 구성이 없는 기존 워크플로우가 계속 작동함을 의미합니다 — 스크립트는 일치하는 항목을 찾을 때만 자격 증명을 적용합니다.

두 가지 자격 증명 전략이 지원됩니다:

  • profile~/.aws/config의 명명된 AWS CLI 프로필을 사용합니다. 스크립트는 CDK 프로세스에 대해 AWS_PROFILE을 설정합니다.
  • assumeRole — 지정된 역할 ARN으로 STS AssumeRole을 호출하고 임시 자격 증명을 CDK에 전달합니다. 선택적으로 AssumeRole 호출을 위한 소스 자격 증명으로 profile을, 교차 계정 신뢰 정책을 위한 externalId를, 그리고 초 단위의 sessionDuration을 지정할 수 있습니다.

각 스테이지 구성에는 필수 region과 선택적 account가 포함됩니다:

  • region (필수) — 배포할 AWS 리전입니다(예: us-east-1, eu-west-2).
  • account (선택) — AWS 계정 ID입니다. 생략하면 CDK가 배포 시점에 활성 자격 증명에서 이를 추론합니다. CDK가 계정과 리전을 해석하는 방법은 CDK 환경 문서를 참조하세요.

생성된 main.ts는 구성에서 이러한 값을 읽어 CDK 합성 및 배포가 동일한 환경 설정을 사용하도록 합니다:

src/main.ts
const sandboxConfig = resolveStage('packages/infra', 'my-app-sandbox');
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
},
});

공유 스테이지(shared.stages 아래)는 워크스페이스의 모든 인프라 프로젝트에 적용됩니다. 이는 여러 프로젝트가 동일한 샌드박스 계정에 배포될 때 유용합니다 — 각 프로젝트마다 반복하는 대신 자격 증명을 한 번만 정의합니다.

프로젝트별 스테이지(projects['packages/infra'].stages 아래)는 해당 프로젝트에만 적용됩니다. 동일한 스테이지 이름에 대해 둘 다 존재하는 경우, 프로젝트별 항목이 우선합니다.

tRPC API 또는 FastAPI 생성기를 사용하여 API를 생성한 경우, packages/common/constructs에 이미 배포할 수 있는 일부 구성 요소가 있음을 알 수 있습니다.

예를 들어, my-api라는 tRPC API를 생성한 경우, 구성 요소를 가져와서 인스턴스화하여 배포에 필요한 모든 인프라를 추가할 수 있습니다:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyApi } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your API
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}

React Website 생성기를 사용한 경우, packages/common/constructs에 이미 배포할 수 있는 구성 요소가 있음을 알 수 있습니다. 예를 들어:

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your website
new MyWebsite(this, 'MyWebsite');
}
}

build 타겟의 일부로, 기본 컴파일, 린트 및 테스트 타겟을 실행하는 것 외에도, 인프라 프로젝트가 CloudFormation으로 _합성_됩니다. 이는 synth 타겟을 실행하여 독립적으로 실행할 수도 있습니다:

Terminal window
pnpm nx synth <my-infra>

합성된 클라우드 어셈블리는 루트 dist 폴더의 dist/packages/<my-infra-project>/cdk.out 아래에서 찾을 수 있습니다.

synth^assemble에 의존하므로, 합성은 Lambda 번들, 컨테이너 이미지 및 생성된 사양과 같이 스택이 배포하는 아티팩트를 빌드하지만, 모든 업스트림 프로젝트의 린트, 테스트 및 타입 검사 게이트를 실행하지는 않습니다. assemble에 대한 자세한 내용은 Assembling을 참조하세요.

프로젝트에 checkov 타겟이 추가되어 Checkov를 사용하여 인프라에 대한 보안 검사를 실행합니다.

Terminal window
pnpm nx checkov <my-infra>

보안 테스트 결과는 루트 dist 폴더의 dist/packages/<my-infra-project>/checkov 아래에서 찾을 수 있습니다.

리소스에 대해 특정 규칙을 억제하려는 경우가 있을 수 있습니다. 두 가지 방법으로 이를 수행할 수 있습니다:

주어진 구성 요소에 대한 규칙 억제

섹션 제목: “주어진 구성 요소에 대한 규칙 억제”
import { suppressRules } from '@my-scope/common-constructs';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');

하위 구성 요소에 대한 규칙 억제

섹션 제목: “하위 구성 요소에 대한 규칙 억제”
import { suppressRules } from '@my-scope/common-constructs';
// Supresses the CKV_AWS_XXX for the construct or any of its descendants if it is an instance of Bucket
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason', (construct) => construct instanceof Bucket);

AWS 계정에 CDK 애플리케이션을 처음 배포하는 경우, 부트스트랩이 필요합니다. 부트스트랩은 CDK가 배포를 관리하는 데 필요한 리소스(자산용 S3 버킷, IAM 역할 등)를 생성합니다.

먼저, AWS 계정에 대한 자격 증명을 구성했는지 확인하세요.

다음으로, 배포할 각 계정 및 리전에 대해 부트스트랩 명령을 실행합니다:

터미널 창
npx cdk bootstrap aws://<account-id>/<region>

자세한 내용은 CDK 부트스트랩 문서를 참조하세요.

프로젝트에는 각각 다른 상황에 적합한 세 가지 배포 타겟이 있습니다:

타겟사용 용도
deploy-sandbox개발 중 자체 샌드박스 스테이지 배포. 스테이지 인수가 필요하지 않습니다. Express 모드를 사용합니다.
deploy원하는 스테이지 또는 스택을 지정하여 모든 스테이지 배포. 완전한 안정화를 기다립니다.
deploy-ci사전 합성된 클라우드 어셈블리를 사용하여 CI/CD 파이프라인에서 배포. 완전한 안정화를 기다립니다.

deploy-sandboxdeploy^assemble에 의존하므로, 배포하려는 아티팩트만 빌드합니다. deploy-ci는 파이프라인이 이미 빌드한 어셈블리를 배포하므로, 빌드 의존성이 전혀 없습니다.

먼저, AWS 자격 증명이 구성되어 있는지 확인하세요. stageConfig로 생성하고 packages/common/infra-config/src/stages.config.ts에서 스테이지 자격 증명을 구성한 경우, 배포 명령이 대상 스테이지에 대한 올바른 자격 증명을 자동으로 해석하고 적용합니다. 그렇지 않으면 환경에 AWS 자격 증명이 설정되어 있는지 확인하세요(예: AWS_PROFILE 또는 환경 변수를 통해). 사용 가능한 옵션은 AWS 자격 증명 문서를 참조하세요.

deploy-sandbox 타겟은 main.ts가 선언하는 샌드박스 스테이지를 배포하므로, 스테이지 이름을 기억할 필요가 없습니다:

Terminal window
pnpm nx deploy-sandbox <my-infra>

이는 개발하는 동안 AWS에서 애플리케이션의 자체 복사본을 실행하는 가장 빠른 방법입니다.

deploy 타겟은 지정한 스테이지 또는 스택을 배포합니다. 샌드박스 이외의 스테이지나 단일 스택을 배포하는 데 사용하세요:

Terminal window
pnpm nx deploy <my-infra> <my-infra>-sandbox/*

main.ts에 정의된 모든 스테이지를 지정할 수 있습니다. 개별 스택을 배포하려면 전체 스택 이름을 제공하세요:

Terminal window
pnpm nx deploy <my-infra> <my-infra>-sandbox/Application

이 타겟은 프로덕션 스테이지를 포함한 모든 스테이지를 지정할 수 있으므로, 전체 리소스 안정화를 기다립니다. 반복하는 스테이지에 대해 express 모드를 선택하려면 --express를 전달하세요.

CI/CD 파이프라인의 일부로 AWS에 배포하는 경우 deploy-ci 타겟을 사용하세요.

Terminal window
pnpm nx deploy-ci <my-infra> my-stage/*

이 타겟은 즉석에서 합성하는 대신 사전 합성된 클라우드 어셈블리를 배포하여, 패키지 버전 변경으로 인한 잠재적인 비결정성을 방지하고 모든 파이프라인 스테이지가 동일한 클라우드 어셈블리를 사용하여 배포하도록 보장합니다. deploy와 마찬가지로 성공을 보고하기 전에 모든 리소스가 완전히 안정화될 때까지 기다리며, deploy와 달리 --express 옵트아웃을 허용하지 않습니다.

프로젝트에는 배포 타겟을 반영하는 세 가지 해체 타겟이 있습니다:

타겟사용 용도
destroy-sandbox자체 샌드박스 스테이지 해체. 스테이지 인수가 필요하지 않습니다.
destroy원하는 스테이지 또는 스택을 지정하여 모든 스테이지 해체.
destroy-ci사전 합성된 클라우드 어셈블리를 사용하여 CI/CD 파이프라인에서 해체.

destroy-sandbox 타겟은 main.ts가 선언하는 샌드박스 스테이지를 해체하므로, 스테이지 이름을 기억할 필요가 없습니다:

Terminal window
pnpm nx destroy-sandbox <my-infra>

해체는 되돌릴 수 없으므로, CDK는 삭제하려는 스택을 확인하도록 요청합니다. --force를 전달하여 확인을 건너뛸 수 있으며, 이는 터미널이 연결되지 않은 경우(예: 스크립트에서) 원하는 동작입니다:

Terminal window
pnpm nx destroy-sandbox <my-infra> --force

destroy 타겟은 지정한 스테이지 또는 스택을 해체합니다:

Terminal window
pnpm nx destroy <my-infra> <my-infra>-sandbox/**

전체 스테이지에는 /*가 아닌 /**를 사용하세요: 해체는 패턴이 선택한 스택만 삭제하며, /*는 웹사이트가 CloudFront 배포를 위해 생성하는 us-east-1 WebACL 스택과 같이 스테이지의 스택 아래에 중첩된 스택을 놓칩니다.

개별 스택을 해체하려면 전체 스택 이름을 제공하세요:

Terminal window
pnpm nx destroy <my-infra> <my-infra>-sandbox/Application

CDK에 대한 자세한 내용은 CDK 개발자 가이드API 참조를 참조하세요.