以下构建规范运行一些命令并最终导出一个变量:
env:
exported-variables:
- PROPERTY_FROM_BUILD
我想在自定义管道阶段中使用此变量,但我不知道如何在此处获取它:
import { Stage, StageProps } from 'aws-cdk-lib';
class MyStage extends Stage {
constructor(scope: Construct, id: string, props: StageProps) {
new Stack(this, 'MyStack', {
PROPERTY_FROM_BUILD: '???'
});
}
}
为了以防万一,让我发布更多详细信息。我的代码管道如下所示:
const codePipeline = new cdk.pipelines.CodePipeline(this, 'MyPipeline', {...});
codePipeline.addStage(new MyStage(this, 'MyStage', {...})
codePipeline.buildPipeline();
如您所见,我只是创建一个管道,添加我的阶段并构建它。完成后,我创建一个代码构建项目和操作来运行我的构建规范:
const project = new cdk.aws_codebuild.PipelineProject(this, 'MyProject', {
buildSpec: cdk.aws_codebuild.BuildSpec.fromSourceFilename(`buildspec.yml`),
});
const action = new cdk.aws_codepipeline_actions.CodeBuildAction({
actionName: 'MyAction',
project: project,
});
codePipeline.pipeline.addStage({
stageName: 'MyActionStage',
actions: [action],
placement: {
rightBefore: codePipeline.pipeline.stage('MyStage')
}
});
它可以工作并生成一个很好的管道。有什么方法可以从变量传递我的
PROPERTY_FROM_BUILD
并在我的堆栈中使用它?
虽然我花了大约一周的时间才弄清楚这一点,但我终究还是成功了。让我把解决方案留在这里,以防其他人遇到这个问题:
在开始之前,使用自定义命名空间扩展您的
CodeBuildAction
,例如:
const action = new cdk.aws_codepipeline_actions.CodeBuildAction({
actionName: 'MyAction',
project: project,
variablesNamespace: 'my_action_namespace',
});
首先,你必须找出部署阶段的索引,例如:
const deployIdx = codePipeline.pipeline.stages.indexOf(codePipeline.pipeline.stage('Deploy'));
然后,查找“changeset Replace”类型的所有操作:
const actionsIdxs = codePipeline.pipeline.stage('Deploy').actions.filter(x => x.actionProperties.category === 'Deploy').map((x,i)=>i);
接下来,使用此 Escape Hatches 功能编辑生成的模板并将 管道变量 作为
ParameterOverrides
附加到所有部署操作:
const cfnPipeline = codePipeline.pipeline.node.findChild('Resource') as cdk.aws_codepipeline.CfnPipeline;
for(const i of actionsIdxs){
cfnPipeline.addOverride(
`Properties.Stages.${deployIdx}.Actions.${i}.Configuration.ParameterOverrides`,
JSON.stringify({
// Use lowercase-only here to match the autogenerated name of the CfnParameter.
propertyfrombuild: "#{my_action_namespace.PROPERTY_FROM_BUILD}"
}));
}
最后,在我的堆栈中,我可以像这样访问该值:
const PROPERTY_FROM_BUILD = new cdk.CfnParameter(this, 'propertyfrombuild').valueAsString;
确保将变量命名为全小写且不含特殊字符,并将其放置在堆栈中(而不是子构造中)。
显然这不是一个完整的答案,而是我为实现此目的所做的要点。
构建规范:
env:
exported-variables:
# Make the JAR filename available to the CodePipeline
- JAR_OUTPUT_NAME
phases:
build:
commands:
# Set the output variable
- JAR_OUTPUT_NAME=App-${CODEBUILD_RESOLVED_SOURCE_VERSION:0:7}.jar
# Your build steps would go here...
管道中的构建操作:
const buildAction = new codepipelineActions.CodeBuildAction({
actionName: 'Build',
project: codeBuildProject,
input: sourceOutput,
outputs: [codeBuildOutput],
variablesNamespace: 'BuildVariables',
});
使用输出变量的操作:
const prepareAction = new codepipelineActions.CloudFormationCreateReplaceChangeSetAction({
actionName: 'App.Prepare',
stackName: 'App',
changeSetName: 'codepipeline-#{codepipeline.PipelineExecutionId}',
templatePath: codeBuildOutput.atPath('stack.yml'),
templateConfiguration: codeBuildOutput.atPath(
`app-parameters.json`
),
parameterOverrides: {
// Here we use the output variable from CodeBuild
CodeContentFileKey: `app/code/${buildAction.variable('JAR_OUTPUT_NAME')}`,
},
cfnCapabilities: [cdk.CfnCapabilities.ANONYMOUS_IAM],
adminPermissions: true,
account: deployEnv.account,
region: deployEnv.region,
role: cdkDeploymentRoles[deployEnv.environment],
deploymentRole: cdkCloudformationExecRoles[deployEnv.environment],
runOrder: 1,
});