迭代模板中的 AWS cloudformation 资源数组

Posted

技术标签:

【中文标题】迭代模板中的 AWS cloudformation 资源数组【英文标题】:Iterate over array of AWS cloudformation resources in template 【发布时间】:2018-10-08 08:04:46 【问题描述】:

从 yml(或 json)模板在 AWS CloudFormation 中创建资源时,是否可以迭代数组以保持模板简短易读。例如,我有一个 Appsync 项目,我必须在其中创建一堆几乎相同的 AWS 类型“AWS::AppSync::Resolver”的解析器。在我与 Cloud Formation 一起使用的 YML 模板中,1 个这样的资源可能看起来像这样

Resource:
 GraphQlAddPostsResolver:
      Type: "AWS::AppSync::Resolver"
      DependsOn: GraphQlSchema
      Properties:
        ApiId:
          Fn::GetAtt: [GraphQlApi, ApiId]
        TypeName: Mutation #<---
        FieldName: addPost #<----
        DataSourceName:
          Fn::GetAtt: [GraphQlLambdaDataSource, Name]
        RequestMappingTemplate: |
          
              "version" : "2017-02-28",
              "operation": "Invoke",
              "payload": 
                  "field": "addPost", #<---
                  "context": $util.toJson($context)
              
          
        ResponseMappingTemplate: |
          $util.toJson($context.result)

我可能有十几个或更多这样的解析器,唯一的区别是我用&lt;---- 指示的位置。有没有办法迭代一个值数组,比如说

- Field: addPost
  Type: Mutation
- Field: allPosts
  Type: Query
- Field: getPost
  Type: Query
## etc...

【问题讨论】:

【参考方案1】:

这在 AWS CloudFormation 中是不可能的。您可以使用嵌套堆栈解决您的问题。使用AWS::CloudFormation::Stack 资源。

  FirstResolver:
    Type: AWS::CloudFormation::Stack
    DependsOn: GraphQlSchema
    Properties:
      TemplateURL: ./app-sync-resolver.yml
      Parameters:
        ApiId: !GetAtt GraphQlApi.ApiId
        DataSourceName: !GetAtt GraphQlLambdaDataSource.Name
        Field: addPost
        Type: Mutation

  SecondResolver:
    Type: AWS::CloudFormation::Stack
    DependsOn: GraphQlSchema
    Properties:
      TemplateURL: ./app-sync-resolver.yml
      Parameters:
        ApiId: !GetAtt GraphQlApi.ApiId
        DataSourceName: !GetAtt GraphQlLambdaDataSource.Name
        Field: allPosts
        Type: Query

app-sync-resolver.yml 看起来像这样(未测试!

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ApiId:
    Type: String
  DataSourceName:
    Type: String
  Type:
    Type: String
  Field:
    Type: String
Resource:
 GraphQLResolver:
      Type: AWS::AppSync::Resolver
      Properties:
        ApiId: !Ref ApiId
        TypeName: !Ref Type
        FieldName: !Ref Field
        DataSourceName: !Ref DataSourceName
        RequestMappingTemplate: |
          
              "version" : "2017-02-28",
              "operation": "Invoke",
              "payload": 
                  "field": "$Field",
                  "context": $util.toJson($context)
              
          
        ResponseMappingTemplate: |
          $util.toJson($context.result)

【讨论】:

【参考方案2】:

不,你不能。 Cloudformation 是一个很棒的工具,但它也有其局限性。

您可能想看看 Jinja 或 Troposphere (python)。

【讨论】:

以上是关于迭代模板中的 AWS cloudformation 资源数组的主要内容,如果未能解决你的问题,请参考以下文章

AWS CloudFormer 支持哪些 AWS 服务?

将特定 AWS API Gateway 阶段连接到 CloudFormation 模板中的特定 Lambda 别名

如何使用 CloudFormation 模板更新现有 AWS API Gateway

用于 ec2 实例中的现场请求的 aws cloudformation 模板

AWS cloudformation 错误:模板验证错误:模板错误:资源 NotificationsTopic 不支持 Fn::GetAtt 中的属性类型 Arn

AWS API Gateway REST API 是不是没有设置来禁用 CloudFormation 模板中的 execute-api 端点?