与现有代码管道一起使用的 AWS CDK 管道
Posted
技术标签:
【中文标题】与现有代码管道一起使用的 AWS CDK 管道【英文标题】:AWS CDK Pipelines using with an existing codepipeline 【发布时间】:2021-10-18 08:29:14 【问题描述】:@aws-cdk/pipelines 的文档似乎建议可以使用 codePipeline
属性将 CDK 管道添加到现有的 @aws-cdk/aws-codepipeline/Pipeline:https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_pipelines.CodePipeline.html
codePipeline? Pipeline An existing Pipeline to be reused and built upon.
但是,我无法使其正常工作,并且在cdk synth
步骤中遇到多个错误,具体取决于我尝试设置它的方式。据我所知,目前还没有任何文档可以涵盖这种情况。
基本上,我们正在尝试创建一个运行类似以下内容的管道:
克隆 lint / 类型检查 / 单元测试 cdk 部署到测试环境 集成测试 部署到 preprod 冒烟测试 人工审批 部署到产品我猜只是不清楚这个 codebuild 管道和 cdk 管道之间的区别。此外,阶段的命名约定似乎有点不清楚 - 参考这个问题:https://github.com/aws/aws-cdk/issues/15945
参见:https://github.com/ChrisSargent/cdk-issues/blob/pipelines/lib/cdk-test-stack.ts 及以下:
import * as cdk from "@aws-cdk/core";
import * as pipelines from "@aws-cdk/pipelines";
import * as codepipeline from "@aws-cdk/aws-codepipeline";
import * as codepipeline_actions from "@aws-cdk/aws-codepipeline-actions";
export class CdkTestStack extends cdk.Stack
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps)
super(scope, id, props);
const cdkInput = pipelines.CodePipelineSource.gitHub(
"ChrisSargent/cdk-issues",
"pipelines"
);
// Setup the code source action
const sourceOutput = new codepipeline.Artifact();
const sourceAction = new codepipeline_actions.GitHubSourceAction(
owner: "ChrisSargent",
repo: "cdk-issues",
branch: "pipelines",
actionName: "SourceAction",
output: sourceOutput,
oauthToken: cdk.SecretValue.secretsManager("git/ChrisSargent"),
);
const pipeline = new codepipeline.Pipeline(this, "Pipeline",
stages: [
actions: [sourceAction],
stageName: "GitSource",
,
],
);
const cdkPipeline = new pipelines.CodePipeline(this, "CDKPipeline",
codePipeline: pipeline,
synth: new pipelines.ShellStep("Synth",
// Without input, we get: Error: CodeBuild action 'Synth' requires an input (and the pipeline doesn't have a Source to fall back to). Add an input or a pipeline source.
// With input, we get:Error: Validation failed with the following errors: Source actions may only occur in first stage
input: cdkInput,
commands: ["yarn install --frozen-lockfile", "npx cdk synth"],
),
);
// Produces: Stage 'PreProd' must have at least one action
// pipeline.addStage(new MyApplication(this, "PreProd"));
// Produces: The given Stage construct ('CdkTestStack/PreProd') should contain at least one Stack
cdkPipeline.addStage(new MyApplication(this, "PreProd"));
class MyApplication extends cdk.Stage
constructor(scope: cdk.Construct, id: string, props?: cdk.StageProps)
super(scope, id, props);
console.log("Nothing to deploy");
任何有关这方面的指导或经验将不胜感激。
【问题讨论】:
【参考方案1】:首先,错误Pipeline must have at least two stages
是正确的。
您只有 GitHub checkout/clone 命令作为一个阶段。
对于第二阶段,您可以使用 CodeBuild 项目来编译/lint/单元测试...如您所述。
但是,您希望如何处理已编译的工件?
构建容器以便稍后部署它们?
如果是这样,CDK 有更好的方法来做到这一点 (DockerImageAsset
)。
这也可以节省您预先存在的管道,您可以直接使用 CDK 管道。
请您尝试设置属性restartExecutionOnUpdate: true
,
你的常规管道,就像我下面的 sn-p 一样?
const pipeline = new codepipeline.Pipeline(this, "Pipeline",
restartExecutionOnUpdate: true,
stages: [
actions: [sourceAction],
stageName: "GitSource",
,
],
);
这是 CDK 管道的自突变能力所必需的。
【讨论】:
感谢您的回答。我更新了我的代码以包含第二个“阶段”,我实际上认为我的代码中的cdkPipeline
会根据需要添加多个阶段。但是,这并没有让我通过 input
错误,这似乎只是现在的 catch-22。
“但是,您想对编译后的工件做什么?”我们所做的一切都是无服务器的,没有 Docker 容器。 lambda 是用 Golang 编写的,并内置在 cdk synth 命令中。构建/部署后,我们希望将端到端测试作为管道中的一个新阶段运行
@ChrisSargent 我这里的情况非常相似。你发现这里有什么工作吗?
@jobcrazy - 不是真的,我或多或少地放弃了 CodePipeline,主要是因为重新部署失败的堆栈的问题。也可以看:github.com/aws/aws-cdk/issues/16488
@ChrisSargent,我有一个解决方案,请查看我发布的答案。【参考方案2】:
我可以通过在 CDK 管道中添加只有 pre
和 post
步骤的波/阶段来实现类似的效果,示例代码如下所示,我正在修改您的原始代码 sn-p:
import * as cdk from "@aws-cdk/core";
import * as pipelines from "@aws-cdk/pipelines";
import * as codepipeline from "@aws-cdk/aws-codepipeline";
import * as codepipeline_actions from "@aws-cdk/aws-codepipeline-actions";
export class CdkTestStack extends cdk.Stack
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps)
super(scope, id, props);
const cdkInput = pipelines.CodePipelineSource.gitHub(
"ChrisSargent/cdk-issues",
"pipelines"
);
const cdkPipeline = new pipelines.CodePipeline(this, "CDKPipeline",
selfMutation: true,
crossAccountKeys: true, //can be false if you don't need to deploy to a different account.
pipelineName,
synth: new pipelines.ShellStep("Synth",
// Without input, we get: Error: CodeBuild action 'Synth' requires an input (and the pipeline doesn't have a Source to fall back to). Add an input or a pipeline source.
// With input, we get:Error: Validation failed with the following errors: Source actions may only occur in first stage
input: cdkInput,
commands: ["yarn install --frozen-lockfile", "npx cdk synth"],
primaryOutputDirectory: 'cdk.out'
),
);
// add any additional test step here, they will run parallels in waves
cdkPipeline.addWave('test', post: [provideUnitTestStep(this, 'unitTest')]);
// add a manual approve step if needed.
cdkPipeline.addWave('promotion', post: [new ManualApprovalStep('PromoteToUat')]);
// Produces: Stage 'PreProd' must have at least one action
// pipeline.addStage(new MyApplication(this, "PreProd"));
// Produces: The given Stage construct ('CdkTestStack/PreProd') should contain at least one Stack
cdkPipeline.addStage(new MyApplication(this, "PreProd"));
class MyApplication extends cdk.Stage
constructor(scope: cdk.Construct, id: string, props?: cdk.StageProps)
super(scope, id, props);
console.log("Nothing to deploy");
值得注意的是,您可能需要将编写 Codebuild
操作的方式隐蔽到新的 cdk CodeBuildStep
。一个示例单元测试步骤可能如下所示:
const provideUnitTestStep = (
id: string
): cdkpipeline.CodeBuildStep =>
const props: CodeBuildStepProps =
partialBuildSpec: codebuild.BuildSpec.fromObject(
version: '0.2',
env:
variables:
DEFINE_VARIBLES: 'someVariables'
,
phases:
install:
commands: [
'install some dependencies',
]
,
build:
commands: [
'run some test!'
]
),
commands: [],
buildEnvironment:
buildImage: codebuild.LinuxBuildImage.STANDARD_5_0
;
return new cdkpipeline.CodeBuildStep(`$id`, props);
;
检索下划线CodeBuild
项目Role
并不是那么简单(并且足够简单),您需要在CodeBuildStep
道具中传递rolePolicyStatements
属性以授予测试所需的额外权限。
【讨论】:
好的,有道理。最后我们决定放弃 CodePipeline,因为我们一直遇到它的限制。以上是关于与现有代码管道一起使用的 AWS CDK 管道的主要内容,如果未能解决你的问题,请参考以下文章
AWS CDK - 多个堆栈 - 找不到 Lambda 代码位置的参数