如何从CDK Pipeline创建多环境专属流水线并引入跨仓基础设施代码?
解决方案:在CDK Pipeline中引入多仓库的基础设施代码
针对你采用主干开发模式、多独立仓库(infra/backend/UI)、多AWS账号部署的场景,有两种主流方案可以解决将其他仓库的基础设施代码引入CDK Pipeline Stage的问题:
方案一:将各仓库的CDK代码发布为可复用包
把infra、backend、UI仓库中的CDK Stage/Stack代码打包成npm(或对应语言的包,比如Python的PyPI包),在CDK Pipeline仓库中直接安装并实例化这些包中的Stage,这是最符合CDK设计理念的方式。
步骤:
在各业务仓库中封装Stage
在infra仓库中编写包含Stack的Stage类,示例(TypeScript):// infra/lib/infra-stage.ts import { Stage, StageProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { InfraStack } from './infra-stack'; export class InfraStage extends Stage { constructor(scope: Construct, id: string, props: StageProps) { super(scope, id, props); // 实例化当前仓库中的基础设施栈 new InfraStack(this, 'InfraStack', { env: props.env }); } }同理在backend和UI仓库中封装
BackendStage、UiStage,并配置package.json(设置正确的main入口、版本号)。发布包到私有仓库
把这些包发布到私有包管理服务(比如AWS CodeArtifact、GitHub Packages),避免公开代码,同时方便流水线拉取。在CDK Pipeline仓库中引入并使用
安装各业务仓库的包后,直接实例化Stage并添加到流水线:// pipeline/lib/pipeline-stack.ts import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { CodePipeline, CodePipelineSource, ShellStep, ManualApprovalStep } from 'aws-cdk-lib/pipelines'; import { InfraStage } from '@your-org/infra-cdk'; import { BackendStage } from '@your-org/backend-cdk'; import { UiStage } from '@your-org/ui-cdk'; export class PipelineStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); const pipeline = new CodePipeline(this, 'AppPipeline', { pipelineName: 'MultiRepoDeploymentPipeline', synth: new ShellStep('SynthPipeline', { input: CodePipelineSource.gitHub('your-org/pipeline', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); // 部署Dev环境(对应develop分支) const devInfra = new InfraStage(this, 'DevInfra', { env: { account: 'DEV_ACCOUNT_ID', region: 'us-east-1' } }); pipeline.addStage(devInfra); const devBackend = new BackendStage(this, 'DevBackend', { env: { account: 'DEV_ACCOUNT_ID', region: 'us-east-1' }, // 可传递InfraStage的输出给Backend,比如数据库端点 dbEndpoint: devInfra.dbEndpoint }); pipeline.addStage(devBackend); pipeline.addStage(new UiStage(this, 'DevUi', { env: { account: 'DEV_ACCOUNT_ID', region: 'us-east-1' } })); // 部署Prod环境(对应release分支,需手动审批) const prodInfra = new InfraStage(this, 'ProdInfra', { env: { account: 'PROD_ACCOUNT_ID', region: 'us-east-1' } }); pipeline.addStage(prodInfra, { // 仅当release分支有变更时触发 trigger: CodePipelineSource.gitHub('your-org/pipeline', 'release').trigger, pre: [new ManualApprovalStep('ApproveProdDeployment')] }); // 同理添加Prod的Backend和UI Stage } }
方案二:在Pipeline步骤中直接拉取其他仓库代码部署
如果不想发布包,可以通过ShellStep直接拉取目标仓库的代码,执行CDK合成和部署命令,适合快速迭代的场景。
示例代码:
// pipeline/lib/pipeline-stack.ts import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { CodePipeline, CodePipelineSource, ShellStep, ManualApprovalStep } from 'aws-cdk-lib/pipelines'; export class PipelineStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); const pipeline = new CodePipeline(this, 'AppPipeline', { pipelineName: 'MultiRepoDirectDeploymentPipeline', synth: new ShellStep('SynthPipeline', { input: CodePipelineSource.gitHub('your-org/pipeline', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); // Dev环境部署Infra pipeline.addStage({ stageName: 'DevInfra', steps: [ new ShellStep('DeployDevInfra', { input: CodePipelineSource.gitHub('your-org/infra', 'develop'), commands: [ 'npm ci', // 若目标账号未CDK Bootstrap,需先执行此命令 'npx cdk bootstrap aws://DEV_ACCOUNT_ID/us-east-1', 'npx cdk deploy --app "npx ts-node bin/infra.ts" --env account=DEV_ACCOUNT_ID --env region=us-east-1 --require-approval never' ] }) ] }); // Dev环境部署Backend pipeline.addStage({ stageName: 'DevBackend', steps: [ new ShellStep('DeployDevBackend', { input: CodePipelineSource.gitHub('your-org/backend', 'develop'), commands: [ 'npm ci', 'npm run build', 'npx cdk deploy --app "npx ts-node bin/backend.ts" --env account=DEV_ACCOUNT_ID --env region=us-east-1 --require-approval never' ] }) ] }); // Prod环境部署Infra(release分支触发,需审批) pipeline.addStage({ stageName: 'ProdInfra', steps: [ new ShellStep('DeployProdInfra', { input: CodePipelineSource.gitHub('your-org/infra', 'release'), commands: [ 'npm ci', 'npx cdk deploy --app "npx ts-node bin/infra.ts" --env account=PROD_ACCOUNT_ID --env region=us-east-1' ] }) ], pre: [new ManualApprovalStep('ApproveProdInfra')] }); } }
关键注意事项
- 跨账号权限:所有目标部署账号必须完成CDK Bootstrap,并且授予流水线所在账号对应的部署权限(可通过
cdk bootstrap --trust参数配置)。 - 版本一致性:方案一中,建议用分支对应包版本(比如develop分支发布beta版,release分支发布稳定版),避免版本冲突。
- 分支触发规则:可通过
trigger参数指定不同Stage对应不同的仓库分支,实现主干开发模式下的环境隔离部署。
内容的提问来源于stack exchange,提问作者Levi
相关产品推荐
相关产品推荐

