Bỏ qua để đến nội dung

Hạ tầng CDK

AWS CDK là một framework để định nghĩa hạ tầng đám mây bằng code và cung cấp nó thông qua AWS CloudFormation.

Trình tạo hạ tầng TypeScript tạo ra một ứng dụng hạ tầng AWS CDK được viết bằng TypeScript. Ứng dụng được tạo ra bao gồm các phương pháp bảo mật tốt nhất thông qua kiểm tra bảo mật Checkov.

Bạn có thể tạo một dự án hạ tầng mới theo hai cách:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra
Bạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --dry-run
Tham sốKiểuMặc địnhMô tả
name Bắt buộcstring-Tên của ứng dụng.
directory stringpackagesThư mục của ứng dụng mới.
subDirectory string-Thư mục con mà dự án được đặt trong đó. Mặc định đây là tên dự án.
stageConfig booleanBật cấu hình stage tập trung (thông tin xác thực, tài khoản, vùng) cho triển khai CDK đa môi trường.
preferInstallDependencies booleantrueCó nên cài đặt dependencies sau khi generator chạy hay không. Đặt thành false để hoãn việc cài đặt khi chạy nhiều generator liên tiếp (việc cài đặt vẫn sẽ chạy nếu cần thiết để các generator tiếp theo có thể tính toán Nx project graph); cài đặt một lần vào cuối.

Trình tạo sẽ tạo cấu trúc dự án sau trong thư mục <directory>/<name>:

  • Thư mụcsrc
    • main.ts Application entry point instantiating CDK stages to deploy
    • Thư mụcstages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • Thư mụcstacks 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

Nếu bạn đặt tùy chọn stageConfig, trình tạo cũng tạo hai gói chia sẻ để quản lý thông tin xác thực tập trung (nếu chúng chưa tồn tại):

  • Thư mụcpackages/common
    • Thư mụcinfra-config Stage configuration types and credential mappings
      • Thư mụcsrc
        • stages.types.ts Type definitions for stage credentials and config
        • stages.config.ts Your stage-to-credential mappings (edit this)
        • index.ts Re-exports for importing from other packages
    • Thư mụcscripts Centralized deploy/destroy scripts
      • Thư mụcsrc
        • infra-deploy.ts Deploy bin script
        • infra-destroy.ts Destroy bin script
        • Thư mụcstage-credentials/ Shared logic (credential lookup, CDK command building)

Bạn có thể bắt đầu viết hạ tầng CDK của mình bên trong src/stacks/application-stack.ts, ví dụ:

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 sử dụng Stages để nhóm các stack nên được triển khai cùng nhau vào một môi trường cụ thể. File src/main.ts được tạo ra tạo một sandbox stage cho việc phát triển và kiểm tra của riêng bạn:

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

Thuộc tính env cho CDK biết tài khoản AWS và vùng nào để triển khai. CDK_DEFAULT_ACCOUNTCDK_DEFAULT_REGION được CDK CLI tự động phân giải từ thông tin xác thực AWS đang hoạt động của bạn. Xem tài liệu môi trường CDK để biết thêm chi tiết.

Sandbox stage là stage mà target deploy-sandbox triển khai.

Nếu bạn tạo với stageConfig, main.ts đọc tài khoản và vùng từ file cấu hình tập trung thay vì, quay lại biến môi trường khi không có cấu hình nào được đặt:

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

Bạn có thể thêm nhiều stage hơn để triển khai vào các môi trường khác nhau. Ví dụ, các stage betaprod nhắm đến các tài khoản AWS riêng biệt:

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',
},
});

Một Stage nhóm một hoặc nhiều stack. Bạn có thể thêm bao nhiêu stack tùy thích bên trong một stage:

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

Khi bạn có nhiều stage nhắm đến các tài khoản AWS khác nhau, việc quản lý thông tin xác thực thủ công có thể dễ xảy ra lỗi, đặc biệt khi số lượng stage tăng lên.

Tùy chọn stageConfig giải quyết vấn đề này bằng cách tạo hai gói chia sẻ:

  • packages/common/infra-config — Một file cấu hình duy nhất nơi bạn ánh xạ mỗi stage với thông tin xác thực AWS, tài khoản và vùng của nó. Điều này có thể được import từ bất kỳ gói nào trong workspace của bạn, vì vậy main.ts CDK của bạn có thể đọc tài khoản và vùng từ cùng một nguồn sự thật.
  • packages/common/scripts — Các lệnh infra-deployinfra-destroy bao bọc CDK với phân giải thông tin xác thực tự động. Khi bạn chạy deploy, script đọc cấu hình, đặt các biến môi trường AWS phù hợp cho tiến trình con CDK và chạy cdk deploy. Môi trường shell của bạn không bao giờ bị sửa đổi.

Chỉnh sửa packages/common/infra-config/src/stages.config.ts để ánh xạ các stage của bạn với thông tin xác thực 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;

Khi bạn triển khai, ví dụ:

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

Script triển khai:

  1. Trích xuất tên stage my-app-dev từ các đối số lệnh
  2. Tra cứu thông tin xác thực trong cấu hình: đầu tiên dưới projects['packages/infra'], sau đó dưới shared
  3. Nếu tìm thấy, đặt AWS_PROFILE (hoặc assume IAM role) chỉ cho tiến trình con CDK
  4. Nếu không tìm thấy, quay lại bất kỳ thông tin xác thực AWS nào có trong môi trường của bạn

Điều này có nghĩa là các quy trình làm việc hiện có không có bất kỳ cấu hình nào vẫn tiếp tục hoạt động — script chỉ áp dụng thông tin xác thực khi nó tìm thấy một mục khớp.

Hai chiến lược thông tin xác thực được hỗ trợ:

  • profile — Sử dụng một AWS CLI profile được đặt tên từ ~/.aws/config. Script đặt AWS_PROFILE cho tiến trình CDK.
  • assumeRole — Gọi STS AssumeRole với ARN role được chỉ định và truyền thông tin xác thực tạm thời cho CDK. Bạn có thể tùy chọn chỉ định một profile làm thông tin xác thực nguồn cho cuộc gọi AssumeRole, một externalId cho các chính sách tin cậy cross-account và một sessionDuration tính bằng giây.

Mỗi cấu hình stage bao gồm một region bắt buộc và một account tùy chọn:

  • region (bắt buộc) — Vùng AWS để triển khai (ví dụ: us-east-1, eu-west-2).
  • account (tùy chọn) — ID tài khoản AWS. Nếu bỏ qua, CDK suy ra nó từ thông tin xác thực đang hoạt động tại thời điểm triển khai. Xem tài liệu môi trường CDK để biết cách CDK phân giải tài khoản và vùng.

File main.ts được tạo ra đọc các giá trị này từ cấu hình để CDK synthesis và deployment sử dụng cùng các cài đặt môi trường:

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 (dưới shared.stages) áp dụng cho bất kỳ dự án infra nào trong workspace. Điều này hữu ích khi nhiều dự án triển khai vào cùng một tài khoản sandbox — bạn định nghĩa thông tin xác thực một lần thay vì lặp lại chúng cho mỗi dự án.

Project-specific stages (dưới projects['packages/infra'].stages) chỉ áp dụng cho dự án đó. Khi cả hai tồn tại cho cùng một tên stage, mục project-specific được ưu tiên.

Nếu bạn đã sử dụng trình tạo tRPC API hoặc FastAPI để tạo API, bạn sẽ nhận thấy bạn đã có một số construct có sẵn trong packages/common/constructs để triển khai chúng.

Ví dụ, nếu bạn đã tạo một tRPC API có tên my-api, bạn chỉ cần import và khởi tạo construct để thêm tất cả hạ tầng cần thiết để triển khai nó:

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(),
});
}
}

Nếu bạn đã sử dụng trình tạo React Website, bạn sẽ nhận thấy bạn đã có một construct trong packages/common/constructs để triển khai nó. Ví dụ:

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');
}
}

Như một phần của target build của bạn, cũng như chạy các target compile, lint và test mặc định, dự án hạ tầng của bạn được synthesized thành CloudFormation. Điều này cũng có thể được thực thi một cách độc lập, bằng cách chạy target synth:

Terminal window
pnpm nx synth <my-infra>

Bạn sẽ tìm thấy cloud assembly đã được synthesized trong thư mục dist gốc, dưới dist/packages/<my-infra-project>/cdk.out.

Một target checkov được thêm vào dự án của bạn để chạy kiểm tra bảo mật trên hạ tầng của bạn bằng Checkov.

Terminal window
pnpm nx checkov <my-infra>

Bạn sẽ tìm thấy kết quả kiểm tra bảo mật của mình trong thư mục dist gốc, dưới dist/packages/<my-infra-project>/checkov.

Có thể có những trường hợp bạn muốn suppress một số quy tắc nhất định trên các tài nguyên. Bạn có thể làm điều này theo hai cách:

Suppress một quy tắc trên một construct nhất định

Phần tiêu đề “Suppress một quy tắc trên một construct nhất định”
import { suppressRules } from '@my-scope/common-constructs';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');

Suppress một quy tắc trên một construct con cháu

Phần tiêu đề “Suppress một quy tắc trên một construct con cháu”
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);

Nếu bạn đang triển khai một ứng dụng CDK vào một Tài khoản AWS lần đầu tiên, nó sẽ cần được bootstrapped. Bootstrapping tạo ra các tài nguyên mà CDK cần để quản lý các triển khai (một S3 bucket cho assets, IAM roles, v.v.).

Đầu tiên, đảm bảo rằng bạn đã cấu hình thông tin xác thực cho tài khoản AWS của mình.

Tiếp theo, chạy lệnh bootstrap cho mỗi tài khoản và vùng bạn dự định triển khai:

Terminal window
npx cdk bootstrap aws://<account-id>/<region>

Để biết thêm chi tiết, vui lòng tham khảo tài liệu bootstrapping CDK.

Dự án của bạn có ba target triển khai, mỗi target phù hợp với một tình huống khác nhau:

TargetSử dụng nó cho
deploy-sandboxTriển khai sandbox stage của riêng bạn trong quá trình phát triển. Không cần đối số stage.
deployTriển khai bất kỳ stage nào, bằng cách đặt tên stage hoặc stack bạn muốn.
deploy-ciTriển khai từ một CI/CD pipeline, sử dụng một cloud assembly đã được synthesized trước.

Đầu tiên, đảm bảo bạn đã cấu hình thông tin xác thực AWS. Nếu bạn tạo với stageConfig và đã cấu hình thông tin xác thực stage trong packages/common/infra-config/src/stages.config.ts, lệnh deploy sẽ tự động phân giải và áp dụng thông tin xác thực chính xác cho stage đích. Nếu không, đảm bảo thông tin xác thực AWS của bạn được đặt trong môi trường của bạn (ví dụ: thông qua AWS_PROFILE hoặc biến môi trường). Xem tài liệu thông tin xác thực AWS cho các tùy chọn có sẵn.

Target deploy-sandbox triển khai sandbox stage mà main.ts khai báo, vì vậy bạn không cần nhớ tên stage của nó:

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

Đây là cách nhanh nhất để có bản sao ứng dụng của riêng bạn chạy trong AWS trong khi bạn phát triển.

Target deploy triển khai bất kỳ stage hoặc stack nào bạn đặt tên. Sử dụng nó cho các stage khác ngoài sandbox của bạn, hoặc để triển khai một stack duy nhất:

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

Bạn có thể chỉ định bất kỳ stage nào miễn là nó được định nghĩa trong main.ts. Để triển khai một stack riêng lẻ, cung cấp tên stack đầy đủ:

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

Sử dụng target deploy-ci nếu bạn đang triển khai lên AWS như một phần của CI/CD pipeline.

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

Target này khác một chút so với target deploy thông thường ở chỗ nó triển khai một cloud assembly đã được synthesized trước thay vì synthesizing ngay lập tức. Điều này tránh khả năng không xác định tiềm ẩn từ các thay đổi phiên bản gói, đảm bảo rằng mọi giai đoạn pipeline triển khai sử dụng cùng một cloud assembly.

Sử dụng target destroy để phá bỏ các tài nguyên của bạn:

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

Để biết thêm thông tin về CDK, vui lòng tham khảo CDK Developer GuideAPI Reference.