将类型为List <AWS :: EC2 :: Subnet :: Id>的参数传递给嵌套的CloudFormation模板

Ste*_*han 6 amazon-web-services aws-cloudformation

我正在尝试通过使用AWS::CloudFormation::Stack资源类型将CloudFormation模板嵌套到另一个模板中。嵌套模板的参数类型为List<AWS::EC2::Subnet::Id>

单独地,嵌套模板运行得很好。但是,在嵌入AWS控制台时,会显示遇到不受支持的属性ELBSubnetList

更改参数的类型为字符串/逗号分隔列表似乎是一种解决方法,因为dicussed 这里,而是通过AWS控制台interactivly创建模板时,我失去了幻想UI。

您是否知道如何将子网ID列表作为参数传递?

这是嵌入式模板:

{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Parameters" : {
        "ELBSubnetList" : {
            "Type" : "List<AWS::EC2::Subnet::Id>",
            "Description" : "Subnet List for Elastic Loadbalancer"
        },
        "ELBSecurityGroupList": {
            "Type": "List<AWS::EC2::SecurityGroup::Id>",
            "Description": "Security Group List for Elastic Loadbalancer"
        }
    },
    "Resources" : {
        "ELB" : {
            "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
            "Properties" : {
                "Subnets": { "Ref": "ELBSubnetList" },
                "CrossZone" : "true",
                "SecurityGroups": { "Ref": "ELBSecurityGroupList" },
                "LBCookieStickinessPolicy" : [ {
                    "PolicyName" : "CookieBasedPolicy",
                    "CookieExpirationPeriod" : "30"
                }],
                "Listeners" : [ {
                    "LoadBalancerPort" : "80",
                    "InstancePort" : "80",
                    "Protocol" : "HTTP",
                    "PolicyNames" : [ "CookieBasedPolicy" ]
                } ],
                "HealthCheck" : {
                    "Target" : "HTTP:80/wordpress/wp-admin/install.php",
                    "HealthyThreshold" : "2",
                    "UnhealthyThreshold" : "5",
                    "Interval" : "10",
                    "Timeout" : "5"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和嵌入的模板:

{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Parameters": {
        "ChildTemplate": {
            "Type": "String",
            "Default": "https://s3.eu-central-1.amazonaws.com/cf-templates-xxxxxxxxxxx-eu-central-1/sample_child.template"
        },
        "ELBSubnetList" : {
            "Type" : "List<AWS::EC2::Subnet::Id>",
            "Description" : "Subnet List for Elastic Loadbalancer"
        },
        "ELBSecurityGroupList": {
            "Type": "List<AWS::EC2::SecurityGroup::Id>",
            "Description": "Security Group List for Elastic Loadbalancer"
        }
    },
    "Resources": {
        "Child": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": { "Ref": "ChildTemplate" },
                "Parameters": {
                    "ELBSubnetList": { "Ref": "ELBSubnetList" },
                    "ELBSecurityGroupList": { "Ref": "ELBSecurityGroupList" }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

dcr*_*n22 8

要将 SubnetId 列表转换为字符串列表,请结合使用JOINSPLIT

太长了;
在 YAML 中,添加

!Split [',', !Join [',', !Ref SubnetIds]]
Run Code Online (Sandbox Code Playgroud)

完整的答案分为两部分。

第 1 部分:加入

SubnetIds是类型列表Subnet.IdJOIN会将所有 ID 合并为一个字符串。JOIN例如,作为分隔符的子网 ID 列表,如下:

[abc, def, hij]=> "abc,def,hij"

第 2 部分:分割

现在让我们获取第 1 部分的输出以及SPLIT分隔符,

"abc,def,hij"=>["abc", "def", "hij"]


这是我创建计划任务的用例示例:

AWSTemplateFormatVersion: '2010-09-09'
Parameters
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Select at least two subnets in your selected VPC.

  ScheduleTask:
    Type: AWS::Events::Rule
    Properties:
      Description: !Sub 'Trigger Sitemap Generation according to the specified schedule'
      ScheduleExpression: !Ref CronExpression
      State: ENABLED
      Targets:
      - Id: 'targetId'
        Arn: !GetAtt ECSCluster.Arn
        RoleArn: !GetAtt ECSEventsRole.Arn
        EcsParameters:
          TaskDefinitionArn: !Ref TaskDefinition
          TaskCount: 1
          LaunchType: 'FARGATE'
          PlatformVersion: 'LATEST'
          NetworkConfiguration:
            AwsVpcConfiguration:
              AssignPublicIp: ENABLED
              SecurityGroups:
                - !Ref SecurityGroup
              Subnets: !Split [',', !Join [',', !Ref SubnetIds]]

Run Code Online (Sandbox Code Playgroud)


Ste*_*han 5

列表可以转换为字符串,反之亦然。所以工作调用是

{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Parameters": {
        "ChildTemplate": {
            "Type": "String",
            "Default": "https://s3.eu-central-1.amazonaws.com/cf-templates-xxxxxxxxxxx-eu-central-1/sample_child.template"
        },
        "ELBSubnetList" : {
            "Type" : "List<AWS::EC2::Subnet::Id>",
            "Description" : "Subnet List for Elastic Loadbalancer"
        },
        "ELBSecurityGroupList": {
            "Type": "List<AWS::EC2::SecurityGroup::Id>",
            "Description": "Security Group List for Elastic Loadbalancer"
        }
    },
    "Resources": {
        "Child": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": { "Ref": "ChildTemplate" },
                "Parameters": {
                    "ELBSubnetList": {"Fn::Join": [",", { "Ref": "ELBSubnetList" }]},
                    "ELBSecurityGroupList": {"Fn::Join": [",", { "Ref": "ELBSecurityGroupList" }]}
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你好呀。这正是我想要做的,但它就是行不通。我将子网作为参数列表获取,如 `Subnets": "List&lt;AWS::...&gt;` 但当我尝试使用 `Subnets: !Join [",", [ !Ref Subnets 将其传递到嵌套堆栈时] ]`(在 yaml 中)CloudFormation 因“模板验证错误:模板错误:每个 Fn::Join 对象需要两个参数”而中断,(1) 字符串分隔符和 (2) 要连接的字符串列表或返回的函数要连接的字符串列表(例如 Fn::GetAZs)。` 我错过了什么吗?!Ref Subnets 应该是一个列表,不是吗?任何建议欢迎 (2认同)

小智 5

在YAML中,您需要使用“选择”“拆分”子网。例如,有两个子网:

!Join [",", [!Select [0, !Ref Subnets], !Select [1, !Ref Subnets]]]
Run Code Online (Sandbox Code Playgroud)

  • 下面的代码会更优雅 - 适用于任何数组大小: !Join [",", !Ref Subnets] (2认同)

小智 5

使用以下摘录成功地在YAML中构建:

Parameters:
  pSubnetIDs:
    Description: The array of Subnet IDs for the Subnet group
    Type: List<AWS::EC2::Subnet::Id>
Resources:
  rDBSubnetGroup:
    Type: "AWS::RDS::DBSubnetGroup"
    Properties: 
      DBSubnetGroupDescription: The subnet group for the RDS instance
      SubnetIds: !Ref pSubnetIDs
Run Code Online (Sandbox Code Playgroud)

我尝试了一堆!Join和!Ref的变体,但均未成功。事实证明,这只是列表的简单!