【问题标题】:How to loop through values in a CloudFormation template如何遍历 CloudFormation 模板中的值
【发布时间】:2024-05-22 20:20:01
【问题描述】:

我正在尝试在 AWS CloudFormation 模板中传递逗号分隔的参数列表,并根据这些值创建多个 Amazon S3 存储桶。

我有一个要求,我将传递一个逗号分隔的国家/地区名称列表,然后 CloudFormation 模板将构建那么多 S3 存储桶(基于传入参数的国家/地区名称)。

例如,如果我在参数中传递fr,us,gb,堆栈应创建fr_myprod_bucketus_myprod_bucketgb_myprod_bucket

我知道 CloudFormation 中没有 for 循环,所以不确定如何实现这一点?

【问题讨论】:

  • 您要在不同区域创建这些存储桶吗?
  • 同一地区没有

标签: amazon-web-services amazon-s3 amazon-cloudformation


【解决方案1】:

你是对的——AWS CloudFormation 中没有 循环 的概念。

AWS CloudFormation 是 declarative language。它描述了期望的输出,但没有说明如何实现结果。

要执行您描述的逻辑,您需要创建一个AWS Lambda-backed Custom Resource。 CloudFormation 将调用提供的 Lambda 函数,然后该函数可以进行任何所需的 API 调用。

模板创建这些存储桶,那么使用 CloudFormation 实际上没有任何好处。只需运行直接执行此操作的程序或脚本即可。

【讨论】:

    【解决方案2】:

    https://palletsprojects.com/p/jinja/ 是向 CloudFormation 模板添加 for 循环的另一个选项。您需要在将 Jinja 模板传递给 CloudFormation 之前对其进行渲染,因为 CloudFormation 本身目前无法处理 Jinja 模板。

      {% for country in ["fr", "us", "gb"] %}
      {{country}}_myprod_bucket:
        Type: AWS::S3::Bucket
      {% endfor %}
    

    Jinja sn-p 将产生的渲染:

      fr_myprod_bucket:
        Type: AWS::S3::Bucket
    
      us_myprod_bucket:
        Type: AWS::S3::Bucket
    
      gb_myprod_bucket:
        Type: AWS::S3::Bucket
    

    【讨论】:

      【解决方案3】:

      使用Count macro

      Count 宏为 CloudFormation 资源提供模板范围的 Count 属性。它允许您指定多个相同类型的资源,而无需剪切和粘贴。

      因此,以下内容:

      AWSTemplateFormatVersion: "2010-09-09"
      Transform: Count
      Resources:
        Bucket:
          Type: AWS::S3::Bucket
          Properties:
            Tags:
              - Key: TestKey
                Value: my bucket %d
          Count: 3
      

      相当于:

      AWSTemplateFormatVersion: "2010-09-09"
      Resources:
        Bucket1:
          Type: AWS::S3::Bucket
          Properties:
            Tags:
              - Key: TestKey
                Value: my bucket 1
        Bucket2:
          Type: AWS::S3::Bucket
          Properties:
            Tags:
              - Key: TestKey
                Value: my bucket 2
        Bucket3:
          Type: AWS::S3::Bucket
          Properties:
            Tags:
              - Key: TestKey
                Value: my bucket 3
      

      【讨论】:

      【解决方案4】:

      另一种方法是使用 CDK,它将 CloudFormation 包装在 Typescript、Python、Java、.NET 或 Golang 中。

      【讨论】:

      • CDK 只让你在编译时进行流控制,而不是在运行时。
      • @Tom 是的,我应该澄清一下,为了使用 CDK,您必须使用高于 CloudFormation 的级别的 CDK。 “编译”(合成器)可以在你喜欢的时候发生。您可以将 (docs.aws.amazon.com/cdk/v2/guide/use_cfn_template.html) CloudFormation 带入您的 CDK。