首页 > 解决方案 > 将列表作为第二个参数传递时,Fn::Sub 的阶梯函数云形成问题

问题描述

我正在尝试使用云形成创建阶跃函数。我想将 lambda arns 作为第二个参数传递给 Fn::Sub 函数。如果我只通过一个 Arn,它会起作用,但当我通过多个 Arn 时会失败。(使用 Fn::Get)。我用 Yml 验证器检查了模板,没有发现任何问题。

步骤的云形成模板定义:

---
Resources:
  ContractDraftStateMachine:
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      RoleArn:
        Fn::GetAtt: [ StepFunctionExecutionRole, Arn ]
      DefinitionString:
        Fn::Sub:
        - |-
          {
            "Comment" : "Sample draft process",
            "StartAt" : "AdvanceWorkflowToDraftInProgress",
            "States" : {
              "AdvanceWorkflowToDraftInProgress" : {
                "Type" : "Task",
                "Resource": "${WorkflowStateChangeLambdaArn}",
                "InputPath":"$.contractId",
                "OutputPath":"$",
                "ResultPath":null,
                "Next" : "CheckQuestionnaireType",
                "Retry" : [
                  {
                    "ErrorEquals" : ["States.TaskTimeout"],
                    "MaxAttempts": 5,
                    "IntervalSeconds": 1
                  },
                  {
                    "ErrorEquals" : ["CustomErrorA"],
                    "MaxAttempts": 5
                  }
                 ],
                "Catch": [
                  {
                    "ErrorEquals": [ "States.ALL" ],
                    "Next": "FailureNotifier"
                  }
                ]
              },
 
              "CheckQuestionnaireType" : {
                "Type" : "Choice",
                "Choices" : [
                  {
                    "Variable" : "$.questionnaireType",
                    "StringEquals" : "CE",
                    "Next" : "PublishQuestionnaireAnswersToCE"
                  },
                  {
                    "Variable" : "$.questionnaireType",
                    "StringEquals" : "LEAF",
                    "Next" : "PublishQuestionnaireAnswersToLeaf"
                  }
                ]
              },
 
              "PublishQuestionnaireAnswersToCE" : {
                "Type" : "Task",
                "Resource": "${WorkflowStateChangeLambdaArn}",
                "Next" : "UpdateCEMetadataAndGenerateDocuments",
                "ResultPath" : null,
                "OutputPath" : "$",
                "Retry" : [
                  {
                    "ErrorEquals" : ["States.TaskTimeout"],
                    "MaxAttempts": 5,
                    "IntervalSeconds": 1
                  },
                  {
                    "ErrorEquals" : ["CustomErrorA"],
                    "MaxAttempts": 5
                  }
                 ],
                "Catch": [
                  {
                    "ErrorEquals": [ "States.ALL" ],
                    "Next": "FailureNotifier"
                  }
                ]
              },
 
              "PublishQuestionnaireAnswersToLeaflet" : {
                "Type" : "Task",
                "Resource": "${WorkflowStateChangeLambdaArn}",
                "End" : true,
                "Retry" : [
                  {
                    "ErrorEquals" : ["States.TaskTimeout"],
                    "MaxAttempts": 5,
                    "IntervalSeconds": 1
                  },
                  {
                    "ErrorEquals" : ["CustomErrorA"],
                    "MaxAttempts": 5
                  }
                 ],
                "Catch": [
                  {
                    "ErrorEquals": [ "States.ALL" ],
                    "Next": "FailureNotifier"
                  }
                ]
              },
 
              "UpdateCEMetadataAndGenerateDocuments" : {
                "Type" : "Task",
                "Resource": "${WorkflowStateChangeLambdaArn}",
                "End" : true,
                "Retry" : [
                  {
                    "ErrorEquals" : ["States.TaskTimeout"],
                    "MaxAttempts": 5,
                    "IntervalSeconds": 1
                  },
                  {
                    "ErrorEquals" : ["CustomErrorA"],
                    "MaxAttempts": 5
                  }
                 ],
                "Catch": [
                  {
                    "ErrorEquals": [ "States.ALL" ],
                    "Next": "FailureNotifier"
                  }
                ]
              },
              "FailureNotifier" : {
                "Type" : "Task",
                "Resource": "${FailureNotifierLambdaArn}",
                "End" : true,
                "Retry" : [
                  {
                    "ErrorEquals" : ["States.TaskTimeout"],
                    "MaxAttempts": 5,
                    "IntervalSeconds": 1
                  },
                  {
                    "ErrorEquals" : ["CustomErrorA"],
                    "MaxAttempts": 5
                  }
                ]
              }
            }
          }
        -  WorkflowStateChangeLambdaArn:
              Fn::GetAtt: [ CreateContractFromQuestionnaireFunction, Arn ]
        -  FailureNotifierLambdaArn:
              Fn::GetAtt: [ CreateContractFromQuestionnaireFunction, Arn ]

错误 - 模板错误:一个或多个 Fn::Sub 内部函数未指定预期参数。指定一个字符串作为第一个参数,以及一个可选的第二个参数来指定要在字符串中替换的值的映射

这只是一个多次使用相同 lambda 的示例,但问题在于将列表/映射传递给 Fn::Sub。

谁能帮我解决这个问题或提供替代解决方案来实现同样的目标?

谢谢,

标签: yamlamazon-cloudformationaws-step-functions

解决方案


Fn::Sub 将单个字符串作为参数或列表。使用列表方法时,列表中应该只有两个元素。第一个元素是字符串(模板),第二个元素是地图。

来自 Fn::Sub 文档

Fn::Sub:
  - String
  - { Var1Name: Var1Value, Var2Name: Var2Value }

注意:由于您只是使用 Fn::Get 属性来构建替换值,因此您可以使用${CreateContractFromQuestionnaireFunction.Arn}并使用Fn::Sub.

例如(为了清楚起见,我缩短了 step 函数。

   Fn::Sub:|-
      {
        "Comment" : "Sample draft process",
        "StartAt" : "AdvanceWorkflowToDraftInProgress",
        "States" : {
          "AdvanceWorkflowToDraftInProgress" : {
            "Type" : "Task",
            "Resource": "${CreateContractFromQuestionnaireFunction.Arn}",
            "InputPath":"$.contractId",
            "OutputPath":"$",
            "ResultPath":null,
            "Next" : "CheckQuestionnaireType",
            "Retry" : [
      ...

推荐阅读