您可以在 CodePipeline 中使用“调用 Lambda”操作,将“命名空间”作为该操作的一部分,然后在后续操作(“CloudFormation Deploy”类型或其他类型的好)。
您的“调用 Lambda”操作将类似于:
- Name: increment-version-number
RunOrder: 1
ActionTypeId:
Category: Invoke
Owner: AWS
Version: 1
Provider: Lambda
Configuration:
FunctionName: my-pipeline-executed-function
Namespace: MyResults
CodePipeline 将调用您的 Lambda,并在您的 Lambda 完成时传递一条输入消息,其中包含您将结果传达回 CodePipeline 所需的数据。
您可以在官方 AWS 文档中查看此类 Lambda 的 javascript 示例:https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html
您可以使用任何语言实现您的 Lambda。 Lambda 的关键部分是:
- 解析传入的消息数据包以查找您需要传递回 CodePipeline 以表明您的 Lambda 已完成的标识符。
- 执行您的用例所需的逻辑
- 调用 api 回调到 CodePipeline 以指示成功(或失败) - 即:
putJobSuccessResult (https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_PutJobSuccessResult.html)
或 putJobFailureResult (https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_PutJobFailureResult.html)
如果您成功了,那么您会注意到部分 api 调用有效负载是
outputVariables。您可以在此处返回要在以后执行 CodePipeline 时使用的值。
这是一个伪代码式 Java 示例:
public final void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
{
try {
Object inputJson = jsonProvider.parse(inputStream, StandardCharsets.UTF_8.name());
final String jobId = JsonPath.read(inputJson, "$.['CodePipeline.job'].id");
logger.info("jobId={}", jobId);
try {
final GetJobDetailsResponse jobDetailsResponse = codePipelineClient.getJobDetails(GetJobDetailsRequest.builder()
.jobId(jobId)
.build());
final JobDetails jobDetails = jobDetailsResponse.jobDetails();
final String pipelineName = jobDetails.data().pipelineContext().pipelineName();
logger.info("pipelineName={}", pipelineName);
final Map<String, String> outputVariables = new HashMap<>();
// do your interesting stuff here, populate the outputVariables map as required
final GetPipelineStateResponse pipelineStateResponse = codePipelineClient.getPipelineState(GetPipelineStateRequest.builder()
.name(pipelineName)
.build());
logger.info("marking job {} completed", jobId);
codePipelineClient.putJobSuccessResult(
PutJobSuccessResultRequest.builder()
.jobId(jobId)
.outputVariables(outputVariables)
.build());
} catch (Exception e) {
logger.error("marking job {} failed", jobId);
codePipelineClient.putJobFailureResult(PutJobFailureResultRequest.builder()
.jobId(jobId)
.failureDetails(FailureDetails.builder()
.type(FailureType.JOB_FAILED)
.message(e.getMessage())
.build())
.build());
throw e;
}
}
catch (Exception e) {
logger.error(context.getAwsRequestId(), e);
}
}
您终于可以稍后在管道中使用来自 Lambda 的数据片段!
使用“哈希”表示法从“命名空间”中检索值,例如#{MyResults.myVariableName}.
通过 Cloudformation 操作,您可以选择使用 TemplateConfiguration 和/或 ParameterOverrides 来传递 Cloudformation 参数。对于 Lambda 提取的值,您需要 ParameterOverrides(您可以混合和匹配参数值的来源,即有一些来自TemplateConfiguration,另一些来自ParameterOverrides),它可能看起来像:
- Name: my-deployment
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ActionMode: CREATE_UPDATE
StackName: my-stack-name
TemplatePath: MyArtifacts::packaged-infrastructure.cfn.yaml
TemplateConfiguration: MyArtifacts::pipeline/my-parameters.json
ParameterOverrides: !Sub >
{
"MyParameterFromLambda": "#{MyResults.myVariableName}"
}