我的方法首先是运行一个简单的Lambda函数来创建当前时间戳并将其保存为OutputArtifacts。然后CloudFormation任务导入此工件作为InputArtifacts,并从DateTime属性获取值,通过ParameterOverrides指令将其传递给CloudFormation。
不幸的是,CodePipeline一直报“DateTimeInput”参数无效(显然GetArtifactAtt查找失败)。我认为lambda输出(python:print)没有正确保存为工件?
您知道如何正确传递lambda输出,或者您有更好的实现方法吗?
所有管道组件均使用YAML定义为CloudFormation。以下是相关部分:
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的输入参数,而不想破坏自动化。