【问题标题】:Convert existing CDK App into CDK Pipeline将现有的 CDK 应用程序转换为 CDK 管道
【发布时间】:2022-11-12 03:27:53
【问题描述】:

是否可以将现有的 CDK 应用程序包装到管道中,选择为应用程序创建管道,但如果只想在本地部署应用程序,也可以执行常规的 cdk deploy -all

我们当前的主应用程序看起来像这样(过于简化,但只是为了给出想法):

const app = describeApp()
const coreStack = new CoreStack(app, 'CoreStack')
const domainConfig = new DomainConfig(app, 'DomainConfig')
...

然后我想做的是在底部添加一些内容:

if (process.env.CREATE_PIPELINE) {
    const pipelineApp = new App();
    new PipelineStack(pipelineApp, 'PipelineStack', app);
}

使用 PipelineStack 类可以有效地将主应用程序作为阶段添加到管道中,例如:

export class PipelineStack extends Stack {
    constructor(scope: Construct, id: string, app: App, props?: StackProps) {

        super(scope, id, props);

        const repo = codeCommit.Repository.fromRepositoryName(this, 'Repo', 'XXX')

        const pipeline = new CodePipeline(this, 'Pipeline', {
            pipelineName: 'Pipeline',
            synth: new CodeBuildStep('SynthStep', {
                    input: CodePipelineSource.codeCommit(repo, 'YYY'),
                    installCommands: [
                        'npm install -g yarn',
                        'cd app',
                        'yarn install',
                        'yarn global add aws-cdk'
                    ],
                    commands: [
                        'yarn build',
                        'cdk synth'
                    ]
                }
            )
        });

        pipeline.addStage(app) 
    }
}

这目前抱怨我的舞台没有舞台名称,但如果我添加黑客:

        // @ts-ignore
        app.stageName = 'DeployApp'

然后我在Error: Pipeline stack which uses cross-environment actions must have an explicitly set region 周围出现错误。

我觉得必须有一种更直接的方法来执行此操作,但无需重写我的主应用程序类以仅允许我通过这个新管道进行部署?

【问题讨论】:

    标签: aws-cdk aws-codepipeline


    【解决方案1】:

    是的。这里的重点是“本地”和“管道”部署具有不同的构造层次结构:

    • 本地:App > (CoreStack, DomainConfig)
    • 管道:App > PipelineStack > Stage > (CoreStack, DomainConfig)

    因为堆栈的父级在每种情况下都不同,所以将应用程序的堆栈包装在可重用的构造中很有用。 MyService example in the docs 也使用这种模式。

    // AppStacks.ts
    export class AppStacks extends Construct {
      constructor(scope: cdk.App | cdk.Stage, id: string, props: AppStacksProps) {
        super(scope, id);
        const coreStack = new CoreStack(this, 'CoreStack', props)
        const domainConfig = new DomainConfig(this, 'DomainConfig', props)
      }
    }
    

    对于 *local* (cdk deploy) 部署,包裹在 AppStacks 中的堆栈是应用程序的子级:

    // app.ts
    const app = new App();
    new AppStacks(app, 'Stacks', props);
    

    对于 *pipeline* 部署,您的堆栈是 Stage 的子级,并且 Stage 被添加到 Pipeline。

    // DeployStage.ts
    export class DeployStage extends cdk.Stage {
      constructor(scope: Construct, id: string, props: DeployStageProps) {
        super(scope, id, { ...props, env: props.config.env });
    
        new AppStacks(this, 'Stacks', props);
      }
    }
    
    // app-pipeline.ts
    const app = new App();
    new PipelineStack(app, 'Pipeline', props); // add the stage: pipeline.addStage(new DeployStage...)
    

    我更喜欢将我的管道应用程序设置放在一个单独的文件中。但是您也可以拥有一个带有条件逻辑的“应用程序”文件,就像在 OP 中一样。

    【讨论】:

    • 谢谢,这是有道理的。我认为我的问题来自于我不想拥有两个版本的应用程序定义,因为我们定义了 20 多个堆栈。我们还创建了自己的 App 类扩展,其中包含许多业务逻辑,这为拥有“动态”层次结构增加了进一步的复杂性。我想我可能已经使用上面的代码让它工作了,我只需要在创建管道堆栈时传入相同的 env 属性,以便它具有匹配的帐户/区域。成功后会反馈的!
    猜你喜欢
    • 1970-01-01
    • 2021-09-06
    • 2021-10-18
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    相关资源
    最近更新 更多