amazon-web-services - 使用 CloudFormation 从外部定义文件部署 StepFunctions
问题描述
我正在尝试使用 CloudFormation 部署 stepfunction,并且我想从 S3 中的外部文件中引用实际的 stepfunction 定义。
模板如下所示:
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'
但是,这似乎不受支持,因为我们遇到了错误
Property validation failure: [Value of property {/DefinitionString} does not match type {String}]
我正在为 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'
我怎样才能使这项工作?
解决方案
诀窍是转义 StepFunction DefinitionString 属性,并在外部 CloudFormation 引用文件中包含实际属性 DefinitionString。仅转义 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'
外部阶跃函数定义文件:
{
"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}"}
}
现在,虽然这解决了问题,但在源代码管理中以这种形式维护 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
外部 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
}
}
}
这是创建 AWS Lambda 支持的自定义资源的文档。
这个还是有问题的。Transform/Include 将外部模板布尔属性转换为字符串属性。因此,定义字符串
"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"
}
变成
"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"
}
CloudFormation 然后抱怨 StepFunction 定义无效:
Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: Expected value of type Boolean at /States/HelloWorld/End'
这是 CloudFormation 转换/包含问题吗?AWS 的人可以就此发表声明吗?
推荐阅读
- html - 为什么我的图像在使用样式表时垂直居中而在使用内联样式时位于 div 的顶部?
- r - 使用 r plotly 对异常值进行箱线图注释
- ios - 关闭模态呈现的 ViewController 动画不起作用
- html - 我试图让一个句子部分成为链接,其余的正常文本,我做错了什么?
- java - 如何解析格式 yyyy-MM-ddTHH:mm:ss.SSS+ZZZZ 的 UTC 时间戳
- java - Grails 4 和 Spring Security 4 - 如何更新用户名
- java - 方法返回 False 但预期为 true
- laravel - Laravel 路由参数根本不关心
- core-location - 开发人员如何重置 Mac Catalyst 应用程序的 CLLocationManager 授权状态?
- kubernetes - Kubernetes / Metallb 单一入口点