men*_*ann 6 lambda artifact aws-cloudformation aws-codepipeline
我想使用 CodePipeline 运行 CloudFormation 模板。此模板需要一个需要包含当前日期/时间的输入参数。不幸的是,CloudFormation 本身无法立即生成当前的 DateTime。
我的方法是首先运行一个简单的 Lambda 函数来创建当前时间戳并将其保存为OutputArtifacts. 随后的 CloudFormation 任务将此工件导入为InputArtifacts并从 DateTime 属性中获取值,然后通过ParameterOverrides指令将其传递给 CloudFormation 。
不幸的是,CodePipeline 一直说DateTimeInput参数无效(显然 GetArtifactAtt 查找失败)。我假设 lambda 输出(python:print)没有正确保存为工件?
您是否知道如何正确传递 lambda 输出,或者您是否知道如何以更好的方式实现这一目标?
所有管道组件都使用 CloudFormation 定义为 YAML。以下是相关部分:
拉姆达函数:
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
Run Code Online (Sandbox Code Playgroud)
这是管道任务:
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" ] }
}
Run Code Online (Sandbox Code Playgroud)
更新:我天真并认为会有一个简单的方法。现在我知道使用 lambda 交付一个简单的输出工件是一项更高级的手动任务。
在 python 代码中,必须评估传递的event字典 ( CodePipeline.job) 以查找:
- 预定义的 OutputArtifacts (S3 Bucket/Key) 和
- CodePipeline 提供的临时 S3 会话凭据。
然后必须通过这些凭据初始化 S3 客户端。S3put_object需要在之后运行。
https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html https://forums.aws.amazon.com/thread.jspa?threadID=232174
所以我的问题又是:你们知道如何以更好或更简单的方式实现这一目标吗?
我只想将当前日期和时间作为 CloudFormation 的输入参数,不想破坏自动化。
您应该使用“Fn::GetParam”而不是“Fn::GetArtifactAtt”。根据CloudFormation文档,“Fn::GetArtifactAtt”只能获取artifact的属性,如BucketName、ObjectKey和URL。“Fn::GetParam”可以从工件中的 json 文件中获取值。因此,如果您可以将工件“GetDateTimeOutput”生成为 zip 文件,其中包含具有以下内容的 JSON 文件(例如 param.json)
{ "日期时间": "2018/10/31 13:32:00" }
然后您可以使用 { "Fn::GetParam" : [ "GetDateTimeOutput", "param.json", "DateTime" ] } 来获取时间。
您可以修改 Lambda 函数来执行此操作,或使用 CodeBuild 操作。CodeBuild 负责创建 zip,您只需指定构建命令即可在输出文件夹中创建 JSON 文件。您可以在以下文档中找到有关如何在 CodePipeline 中使用 CodeBuild 的更多信息。
CloudFormation 文档 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-parameter-override-functions.html#w2ab1c13c17b9
CodeBuild 文档 https://docs.aws.amazon.com/codebuild/latest/userguide/how-to-create-pipeline.html
| 归档时间: |
|
| 查看次数: |
2770 次 |
| 最近记录: |