将 List<AWS::EC2::Subnet::Id> 类型的参数传递给嵌套的 CloudFormation 模板
Passing parameters of type List<AWS::EC2::Subnet::Id> to nested CloudFormation template
我正在尝试使用 AWS::CloudFormation::Stack
资源类型将一个 CloudFormation 模板嵌套到另一个模板中。嵌套模板有一个 List<AWS::EC2::Subnet::Id>
.
类型的参数
单独地,嵌套模板运行得很好。但是当嵌入 AWS 控制台时说 Encountered unsupported 属性 ELBSubnetList.
将参数的类型更改为 String/CommaSeparated 列表似乎是一种解决方法,正如所讨论的那样 但在通过 AWS 控制台交互式创建模板时,我会失去花哨的 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"
}
}
}
}
}
以及嵌入的模板:
{
"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" }
}
}
}
}
}
列表可以转换为字符串,反之亦然。所以工作调用是
{
"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" }]}
}
}
}
}
}
在 YAML 中,您需要使用 Select "split" 子网。例如有两个子网:
!Join [",", [!Select [0, !Ref Subnets], !Select [1, !Ref Subnets]]]
使用以下摘录在 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
我尝试了 !Join 和 !Ref 的多种变体,但都没有成功。事实证明这很简单!列表的参考。
要将 SubnetId 列表转换为字符串列表,请结合使用两者 JOIN and SPLIT。
TLDR;
在 YAML 中,添加
!Split [',', !Join [',', !Ref SubnetIds]]
完整答案分为两部分。
第 1 部分:加入
这里SubnetIds
是一个Subnet.Id
类型的列表。 JOIN
将所有 ID 合并为
一弦。例如,以 ,
作为分隔符的子网 ID JOIN
列表如下:
[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]]
也许对另一个人有帮助:但对我来说是这样的:
在子模板中:
SubnetIds:
Description: Choose which subnets should be deployed to
Type: List<AWS::EC2::Subnet::Id>
但在父模板中
SubnetIds:
Description: Choose which subnets should be deployed to
Type: CommaDelimitedList
Stack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: {s3}
Parameters:
SubnetIds: !Join [',', !Ref SubnetIds]
我正在尝试使用 AWS::CloudFormation::Stack
资源类型将一个 CloudFormation 模板嵌套到另一个模板中。嵌套模板有一个 List<AWS::EC2::Subnet::Id>
.
单独地,嵌套模板运行得很好。但是当嵌入 AWS 控制台时说 Encountered unsupported 属性 ELBSubnetList.
将参数的类型更改为 String/CommaSeparated 列表似乎是一种解决方法,正如所讨论的那样
您知道如何将子网 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"
}
}
}
}
}
以及嵌入的模板:
{
"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" }
}
}
}
}
}
列表可以转换为字符串,反之亦然。所以工作调用是
{
"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" }]}
}
}
}
}
}
在 YAML 中,您需要使用 Select "split" 子网。例如有两个子网:
!Join [",", [!Select [0, !Ref Subnets], !Select [1, !Ref Subnets]]]
使用以下摘录在 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
我尝试了 !Join 和 !Ref 的多种变体,但都没有成功。事实证明这很简单!列表的参考。
要将 SubnetId 列表转换为字符串列表,请结合使用两者 JOIN and SPLIT。
TLDR;
在 YAML 中,添加
!Split [',', !Join [',', !Ref SubnetIds]]
完整答案分为两部分。
第 1 部分:加入
这里SubnetIds
是一个Subnet.Id
类型的列表。 JOIN
将所有 ID 合并为
一弦。例如,以 ,
作为分隔符的子网 ID JOIN
列表如下:
[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]]
也许对另一个人有帮助:但对我来说是这样的:
在子模板中:
SubnetIds:
Description: Choose which subnets should be deployed to
Type: List<AWS::EC2::Subnet::Id>
但在父模板中
SubnetIds:
Description: Choose which subnets should be deployed to
Type: CommaDelimitedList
Stack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: {s3}
Parameters:
SubnetIds: !Join [',', !Ref SubnetIds]