同时用于多个分支的 CDK 流水线

CDK pipeline for multiple branches at the same time

我希望始终为开发和主分支部署 CI-CD 管道。开发人员在需要时手动创建功能分支的管道。

我正在使用来自 https://github.com/awslabs/aws-simple-cicd

的管道

在项目-config.json 中,我们有:

"Backend": [
  {
    "pipelineName": "backend",
    "ccRepoName": "backend",
    "branch": "master",
    "type": "BitBucket",
    "cron": ""
  }
],

步骤 1. 为分支 master 部署的管道

第 2 步。编辑项目-config.json 并更改分支名称:

 "Backend": [
      {
        "pipelineName": "backend",
        "ccRepoName": "backend",
        "branch": "develop",
        "type": "BitBucket",
        "cron": ""
      }
    ],

步骤 3. 为 develop 分支部署管道

在这个阶段,它删除主分支的管道并为开发分支部署它。我们如何才能同时保持多个分支的流水线?

您可以根据要构建的分支定义多个管道堆栈

我已使用以下方法成功完成此操作(使用 Python)

# app.py
from aws_cdk import core
from my_project.pipeline_stack import PipelineStack

app = core.App()

PipelineStack(app, "project-master-branch",
    branch="main"
)

PipelineStack(app, "project-develop-branch",
    branch="develop"
)

PipelineStack 看起来像

# my_project/pipeline_stack.py

from aws_cdk import (
    core,
    pipelines,
    aws_codepipeline as codepipeline,
    aws_codepipeline_actions as cpactions
)

class PipelineStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, branch: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        source_artifact = codepipeline.Artifact()
        cloud_assembly_artifact = codepipeline.Artifact()

        pipeline = pipelines.CdkPipeline(
            self,
            "Pipeline",
            cloud_assembly_artifact=cloud_assembly_artifact,
            pipeline_name=f"my-pipeline-{branch}",
            source_action=cpactions.BitBucketSourceAction(
                ... # your Bitbucket details
                branch=branch  # taking the main or develop branch
            ),
            synth_action=pipelines.SimpleSynthAction(
                source_artifact=source_artifact,
                cloud_assembly_artifact=cloud_assembly_artifact,
                install_command="npm i -g aws-cdk",
                synth_command="cdk synth",
                ... # other options you can provide
            )
        )

这将创建两个代码管道,响应和部署以响应对 maindevelop

的更改

maafk 提供的答案是一个很好的答案。但是,在我们的案例中,出于合规性原因,我们不能为从同一 AWS 账户配置的各种环境设置不同的管道。因此,在我们的环境中,我们有一个开发 AWS 帐户、一个暂存帐户和一个生产帐户。开发、暂存和生产环境的每个管道都需要从其自己的 AWS 账户进行配置。此外,我们的生产账户需要与其他没有连接的账户完全隔离,与开发账户和临时账户之间没有连接。最重要的是,我们的开发人员需要为不同的开发分支创建管道。我们没有简单的方法来管理所有这一切,而不是最终创建跨多个 aws 账户的各种管道,我们只需要一个用于生产,一个用于暂存。我们提出了以下解决方案,它通常允许部署任意数量的管道,而无需在 cdk 源代码中检查任何与分支相关的绑定。

我们正在创建一个 CodePipeline,如下所示:

const branch = this.node.tryGetContext("branch");

new CodePipeline(this, createResourceName(this.node, "CodePipeline"), {
  pipelineName: createResourceName(this.node, "CodePipeline"),
  synth: new CodeBuildStep("Synth", {
    input: ...,
    env: { // The trick is to create an environment variable where the branch name is stored.
      "BRANCH": branch,
    },
    commands: [
      "npm ci",
      "npm run build",
      "npx cdk synth -c branch=$BRANCH", // During synthesis the environment variable is passed in as the branch name to the cdk context.
    ]
  })
});

// This is just for generating resource names based on the pipeline branch
export function createResourceName(node: ConstructNode, resourceName: string) {
  const branch = node.tryGetContext("branch");
  return `${branch}-${resourceName}`;
}

这里的技巧在于在综合过程中如何解析分支变量。它实际上是从 cdk 上下文中查找的。开发人员第一次从新的开发分支(例如分支“bug123”)提供管道时,使用如下命令部署 cdk 应用程序:cdk deploy -c branch=bug123。这通常从本地工作站执行。在综合期间,从 cdk 上下文中检索分支。同时,第一次部署在负责合成CDK app的CodeBuild项目中创建一个名为BRANCH的环境变量。这就像把管道的分支名称写在石头上一样。

管道第二次运行时,例如因为开发人员将一些代码签入分支,为合成应用而运行的命令是在管道的命令部分中定义的命令:npx cdk synth -c branch=$BRANCH.由于在第一次部署期间设置了环境变量,现在相同的分支名称被传递到 cdk 上下文。结果,cdk 代码中的分支变量再次从上下文中解析为创建管道时使用的原始分支名称。

这样,就可以创建多个分支并为每个分支部署新的管道,而无需担心或在源代码中维护分支和管道之间的任何映射。