从外部定义文件使用 CloudFormation 部署 StepFunctions

Ali*_*cob 6 amazon-web-services aws-cloudformation aws-step-functions

我正在尝试使用 CloudFormation 部署步进函数,并且我想从 S3 中的外部文件中引用实际的步进函数定义。

模板如下所示:

StepFunction1: 
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      StateMachineName: !Ref StepFunction1SampleName
      RoleArn: !GetAtt StepFunctionExecutionRole.Arn
      DefinitionString:  
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: 
              Fn::Sub: 's3://${ArtifactsBucketName}/StepFunctions/StepFunction1/definition.json'
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不受支持,因为我们收到错误

Property validation failure: [Value of property {/DefinitionString} does not match type {String}]
Run Code Online (Sandbox Code Playgroud)

我正在为 API 做类似的事情,从外部 swagger 文件中引用实际的 API 定义,这似乎工作正常。

例子:

SearchAPI:
    Type: "AWS::Serverless::Api"
    Properties:
      Name: myAPI
      StageName: latest
      DefinitionBody: 
        Fn::Transform:
          Name: AWS::Include
          Parameters:            
            Location: 
              Fn::Sub: 's3://${ArtifactsBucketName}/ApiGateway/myAPI/swagger.yaml'
Run Code Online (Sandbox Code Playgroud)

我怎样才能使这项工作?

Ali*_*cob 2

诀窍是转义 StepFunction DefinitionString 属性,并将实际属性 DefinitionString 包含在外部 CloudFormation 引用文件中。仅转义 stepfunction 定义字符串将会失败,CloudFormation 会抱怨引用的 Transform/Include 模板不是有效的 yaml/json。它是这样的: 模板:

StepFunction1: 
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      StateMachineName: !Ref StepFunction1SampleName
      RoleArn: !GetAtt StepFunctionExecutionRole.Arn      
      Fn::Transform:
        Name: AWS::Include
        Parameters:
          Location: 
            Fn::Sub: 's3://${ArtifactsBucketName}/StepFunctions/StepFunction1/definition.json'
Run Code Online (Sandbox Code Playgroud)

外部阶跃函数定义文件:

{
    "DefinitionString" : {"Fn::Sub" : "{\r\n  \"Comment\": \"A Retry example of the Amazon States Language using an AWS Lambda Function\",\r\n  \"StartAt\": \"HelloWorld\",\r\n  \"States\": {\r\n    \"HelloWorld\": {\r\n      \"Type\": \"Task\",\r\n      \"Resource\": \"arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${HelloWorldLambdaFunctionName}\",      \r\n      \"End\": true\r\n    }\r\n  }\r\n}"}
}
Run Code Online (Sandbox Code Playgroud)

现在,虽然这解决了问题,但在源代码管理中以这种形式维护 StepFunction 定义有点困难。

因此,我考虑过使用由 lambda 函数支持的 CloudFormation 自定义资源。lambda 函数将处理实际的 StepFunction DefinitionString 转义部分。

它是这样的: 模板:

StepFunctionParser:
    Type: Custom::AMIInfo
    Properties:
      ServiceToken: myLambdaArn
      DefinitionString: 
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: 
              Fn::Sub: 's3://${ArtifactsBucketName}/StepFunctions/StepFunctionX/definition.json'   
  StepFunctionX: 
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      StateMachineName: StepFunction1SampleNameX
      RoleArn: !GetAtt StepFunctionExecutionRole.Arn      
      DefinitionString: !GetAtt StepFunctionParser.DefinitionString
Run Code Online (Sandbox Code Playgroud)

外部 StepFunction 定义文件:

{
  "Comment": "A Retry example of the Amazon States Language using an AWS Lambda Function",
  "StartAt": "HelloWorld",
  "States": {
    "HelloWorld": {
      "Type": "Task",
      "Resource": {"Fn::Sub" : "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${HelloWorldLambdaFunctionName}" },
      "End": true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是创建 AWS Lambda 支持的自定义资源的文档。

这仍然有一个问题。转换/包含将外部模板布尔属性转换为字符串属性。因此,定义字符串

"DefinitionString": {
            "States": {
                "HelloWorld": {
                    "Type": "Task",
                    "Resource": "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${HelloWorldLambdaFunctionName}",
                    **"End": true**
                }
            },
            "Comment": "A Retry example of the Amazon States Language using an AWS Lambda Function",
            "StartAt": "HelloWorld"
        }
Run Code Online (Sandbox Code Playgroud)

变成

"DefinitionString": {
            "States": {
                "HelloWorld": {
                    "Type": "Task",
                    "Resource": _realLambdaFunctionArn_,
                    **"End": "true"**
                }
            },
            "Comment": "A Retry example of the Amazon States Language using an AWS Lambda Function",
            "StartAt": "HelloWorld"
        }
Run Code Online (Sandbox Code Playgroud)

然后 CloudFormation 抱怨 StepFunction 定义无效:

Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: Expected value of type Boolean at /States/HelloWorld/End' 
Run Code Online (Sandbox Code Playgroud)

这是 CloudFormation 转换/包含问题吗?AWS的人可以对此发表声明吗?