Jon*_*o D 14 amazon-ec2 amazon-web-services aws-cloudformation
我们有一个CloudFormation模板,用于创建EC2实例和安全组(以及许多其他资源),但我们需要能够向同一个EC2实例添加一些其他预先存在的安全组.
我们遇到的问题是,预先存在的安全组的数量并不总是相同,我们希望有一个模板来处理所有情况.
目前,我们有一个输入参数,如下所示:
"WebTierSgAdditional": {
"Type": "String",
"Default": "",
"Description": ""
}
Run Code Online (Sandbox Code Playgroud)
我们将此参数传递给逗号分隔的预先存在的安全组字符串,例如'sg-abc123,sg-abc456'
.
EC2实例的SecurityGroup标记如下所示:
"SecurityGroups": [
{
"Ref": "WebSg"
},
{
"Ref": "WebTierSgAdditional"
}
]
Run Code Online (Sandbox Code Playgroud)
使用此代码,在创建实例时,我们会在AWS控制台中收到此错误:
必须对所有安全组使用group-id或group-name,而不是同时使用
上面的'WebSg'参考是在模板中其他地方创建的安全组之一.如果我们通过输入参数传入组名列表而不是组ID列表,则会出现同样的错误.
当我们将输入参数的"类型"字段更改为"CommaDelimitedList"时,我们会收到错误消息:
属性值SecurityGroups的类型必须是List of String
它显然无法使用字符串连接列表以使其成为新列表.
当参数只包含一个sg id时,所有内容都会成功创建,但是,我们需要能够添加多个sg id.
我们Fn::Join
在SecurityGroups标记中尝试了许多不同的使用组合,但似乎没有任何效果.我们真正需要的是某种"爆炸"功能,用于从参数字符串中提取单个id.
有谁知道一个很好的方法让这个工作?
sor*_*han 10
正如您所知,问题是您需要发送字符串列表作为安全组,虽然CloudFormation为您提供了将字符串列表连接到单个分隔字符串的方法,但它不提供简单的方法用于将分隔的字符串拆分为字符串列表.
不幸的是,我知道如何做到这一点的唯一方法是使用嵌套堆栈.您可以使用参数类型"CommaDelimitedList"将逗号分隔的字符串拆分为字符串列表.
基本方法是这样的:
我用以下2个模板对它进行了测试,结果正常:
主要模板:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters" : {
"SecurityGroups" : {
"Description" : "A comma separated list of security groups to merge with the web security group",
"Type" : "String"
}
},
"Resources" : {
"WebSg" : ... your web security group here,
"Ec2Instance" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"TemplateURL" : "s3 link to the other stack template",
"Parameters" : {
"SecurityGroups" : { "Fn::Join" : [ ",", [ { "Ref" : "WebSg" }, { "Ref" : "SecurityGroups" } ] ] },
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
嵌套模板(由上面的"TemplateURL"链接):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters" : {
"SecurityGroups" : {
"Description" : "The Security Groups to launch the instance with",
"Type" : "CommaDelimitedList"
},
}
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
... etc
"SecurityGroupIds" : { "Ref" : "SecurityGroups" }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我很想知道是否有更好的方法来做到这一点.如你所说,它真的需要一个爆炸功能.
AWS 于2017年1月推出了Fn :: Split,现在可以实现.它并不漂亮,但你实际上是将两个列表转换为字符串,然后将字符串转换回列表.Fn::Join
Fn::Split
Parameters:
WebTierSgAdditional:
Type: CommaDelimitedList
Default: ''
Conditions:
HasWebTierSgAdditional: !Not [ !Equals [ '', !Select [ 0, !Ref WebTierSgAdditional ] ] ]
Resources:
WebSg:
Type: AWS::EC2::SecurityGroup
Properties:
# ...
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
# ...
SecurityGroupIds: !Split
- ','
- !Join
- ','
- - !Ref WebSg
- !If [ HasWebTierSgAdditional, !Join [ ',', !Ref WebTierSgAdditional ], !Ref 'AWS::NoValue' ]
Run Code Online (Sandbox Code Playgroud)
WebTierSgAdditional
以列表开头,但转换为字符串,每个项目用逗号分隔!Join [ ',', !Ref WebTierSgAdditional ]
.这包含在另一个包含的列表中,!Ref WebSg
该列表也被转换为字符串,每个项目用逗号分隔.!Split
将采用字符串并将项目拆分为以逗号分隔的列表.
归档时间: |
|
查看次数: |
11785 次 |
最近记录: |