【发布时间】:2019-04-03 12:57:09
【问题描述】:
我想使用 CodePipeline 运行 CloudFormation 模板。此模板需要一个需要包含当前日期/时间的输入参数。不幸的是,CloudFormation 无法自行生成当前的 DateTime。
我的方法是首先运行一个简单的 Lambda 函数来创建当前时间戳并将其保存为 OutputArtifacts。随后的 CloudFormation 任务将该工件导入为 InputArtifacts,并从 DateTime 属性中获取值,并通过 ParameterOverrides 指令将其传递给 CloudFormation。
不幸的是,CodePipeline 一直说 DateTimeInput 参数无效(显然 GetArtifactAtt 查找失败)。
我假设 lambda 输出(python:print)没有正确保存为工件?
您知道如何正确传递 lambda 输出,或者您知道如何以更好的方式实现这一目标?
所有管道组件都使用 CloudFormation 定义为 YAML。以下是相关部分:
Lambda 函数:
Resources:
...
GetDateTimeFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
Runtime: python2.7
Timeout: '10'
Role: !GetAtt GetDateTimeFunctionExecutionRole.Arn
Code:
ZipFile: |
import datetime
import boto3
import json
code_pipeline = boto3.client('codepipeline')
def lambda_handler(event, context):
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
responseData = {'DateTime':now}
print json.dumps(responseData)
response = code_pipeline.put_job_success_result(jobId=event['CodePipeline.job']['id'])
return response
这里是管道任务:
Resources:
...
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !Ref ArtifactStoreBucket
Type: S3
DisableInboundStageTransitions: []
Name: !Ref PipelineName
RoleArn: !GetAtt PipelineRole.Arn
Stages:
- Name: Deploy
Actions:
- Name: GetDateTime
RunOrder: 1
ActionTypeId:
Category: Invoke
Owner: AWS
Provider: Lambda
Version: '1'
Configuration:
FunctionName: !Ref GetDateTimeFunction
OutputArtifacts:
- Name: GetDateTimeOutput
- Name: CreateStack
RunOrder: 2
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: '1'
InputArtifacts:
- Name: TemplateSource
- Name: GetDateTimeOutput
Configuration:
ActionMode: REPLACE_ON_FAILURE
Capabilities: CAPABILITY_IAM
RoleArn: !GetAtt CloudFormationRole.Arn
StackName: !Ref CFNStackname
TemplatePath: !Sub TemplateSource::${CFNScriptfile}
TemplateConfiguration: !Sub TemplateSource::${CFNConfigfile}
ParameterOverrides: |
{
"DateTimeInput" : { "Fn::GetArtifactAtt" : [ "GetDateTimeOutput", "DateTime" ] }
}
更新:我天真地认为会有一个简单的方法。 现在我知道使用 lambda 交付一个简单的输出工件是一项更高级和手动的任务。
在 python 代码中,必须评估传递的 event 字典 (CodePipeline.job) 以进行查找:
- 预定义的 OutputArtifacts (S3 Bucket/Key) 和
- CodePipeline 提供的临时 S3 会话凭证。
然后必须通过这些凭据初始化 S3 客户端。 S3 put_object 之后需要运行。
https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html https://forums.aws.amazon.com/thread.jspa?threadID=232174
所以我的问题又是:你们知道如何以更好或更简单的方式实现这一目标吗?
我只想将当前日期和时间作为 CloudFormation 的输入参数,不想破坏自动化。
【问题讨论】:
标签: lambda amazon-cloudformation aws-codepipeline artifact