我正在尝试将列表参数从主模板传递到子模板,但是我遇到了两个错误。这些是我在主模板上的当前参数。
"Parameters": {
"ELBSubnets": {
"Default": "subnet-5d8fea67,subnet-3e35cf15",
"Type": "CommaDelimitedList"
},
"LCKeyPair": {
"Default": "key-master",
"Type": "String"
},
"LCSecurityGroups": {
"Default": "sg-10a15c74,sg-880e5fec",
"Type": "CommaDelimitedList"
}
},
传递给子模板时,它们在同一模板上被引用。
"ChildTempate1": {
"Properties": {
"Parameters": {
"ELBSubnets": {
"Ref": "ELBSubnets"
},
"KeyPair": {
"Ref": "LCKeyPair"
},
"LCSecurityGroups": {
"Ref": "LCSecurityGroups"
}
},
在子模板上,声明它们完全相同。
"Parameters": {
"ELBSubnets": {
"Type": "CommaDelimitedList"
},
"LCKeyPair": {
"Type": "String"
},
"LCSecurityGroups": {
"Type": "CommaDelimitedList"
}
},
他们在子模板中的这个方法中被引用。
"KeyName": {
"Ref": "LCKeyPair"
},
"SecurityGroups": {
"Fn::Join": [
",",
[
{
"Ref": "LCSecurityGroups"
}
]
]
}
},
这是模板的另一部分。
"Subnets": {
"Fn::Join": [
",",
[
{
"Ref": "ELBSubnets"
}
]
]
}
},
当我尝试在主模板上使用fn :: join时,它会显示
“模板验证错误:模板错误:每个Fn :: Join对象需要两个参数,(1)字符串分隔符和(2)要连接的字符串列表或返回字符串列表的函数(例如Fn :: GetAZs)加入。“
当我在主模板上不使用fn :: join时,错误是
属性值参数必须是具有String(或简单类型)属性的对象
无论我是否在子模板中使用fn :: join相同的参数。
这两个模板都可以在这里找到:https://github.com/slimg00dy/Troposphere-CloudformationTests
答案 0 :(得分:10)
问题是当在CommaDelimitedList上使用Ref时,你传递一个列表,所以它传递“[a,b,c]”而不是“a,b,c”
因此,在主模板上,我使用Join(“,”)传递列表,使用Join(“”)传递字符串。这样他们被称为“a,b,c”和“String”
在子模板上,我将参数设置为列表的CommaDelimitedLists和String中的String。这是因为他们从主模板传递的方式。
然后我在子模板上使用Ref on the Child模板而不使用Join()。这将CommaDelimitedLists创建为Lists,并将以Join(“”)连接的字符串作为字符串传递。
这是我在主模板上的参数声明。
"Parameters": {
"ELBSubnets": {
"Default": "subnet-5d8fea67,subnet-3e35cf15",
"Type": "CommaDelimitedList"
},
"LCKeyPair": {
"Default": "key-master",
"Type": "CommaDelimitedList"
},
"LCSecurityGroups": {
"Default": "sg-10a15c74,sg-880e5fec",
"Type": "CommaDelimitedList"
}
},
以下是我如何使用Join(“,”),Join(“”)和Ref。由于Ref将CommaDelimitedLists转换为Lists,因此我使用Join(“,”)将它们保存为CommaDelimitedLists并将它们传递给子模板。
对于KeyPair字符串,我确保在父模板上将其声明为CommaDelimitedList并使用Join(“”)连接,这在引用子模板时有效地将其变为字符串。
"Parameters": {
"ELBSubnets": {
"Fn::Join": [
",",
{
"Ref": "ELBSubnets"
}
]
},
"LCKeyPair": {
"Fn::Join": [
" ",
{
"Ref": "LCKeyPair"
}
]
},
"LCSecurityGroups": {
"Fn::Join": [
",",
{
"Ref": "LCSecurityGroups"
}
]
}
},
在子模板上,它们被声明为这样。
"Parameters": {
"ELBSubnets": {
"Type": "CommaDelimitedList"
},
"LCKeyPair": {
"Type": "String"
},
"LCSecurityGroups": {
"Type": "CommaDelimitedList"
}
},
并且它们都是正常引用的,而不使用子模板上的Join。
Subnets": {
"Ref": "ELBSubnets"
}
可能有很多不同的方法可以做到这一点。我可以在子模板而不是父模板上进行连接。但是我更喜欢保持一个模板复杂,其余模板尽可能干净。希望这有助于其他人。
我也应该能够将列表作为列表传递给子模板,然后我收到错误“Unknown parameter type:List”
答案 1 :(得分:4)
CommaDelimtedList只能解析一次,因此在父模板中,您需要将类型设置为“String”,然后在子模板中将其保留为CommaDelimitedList,和以前一样。
问题正在发生,因为CloudFormation正在解析父模板中的CommaDelimitedList,然后它试图在子模板中再次解析它。
答案 2 :(得分:0)
所以我之前的回答有点令人困惑 - 但我认为基础知识仍然存在。最后,当在需要列表的参数中使用CommaDelimitedList时,不应该使用Join()。我刚刚查看了您分享的回购的最新更新,我认为您正走在正确的轨道上。如果您需要更多帮助,请告诉我们!