AWS CodePipeline:将 Lambda 函数输出传递给 CloudFormation

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 的输入参数,不想破坏自动化。

zhn*_*gha 0

您应该使用“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