试图将参数从主模板传递到子模板

Trying to pass parameters from Master to child template

我正在尝试将列表参数从主模板传递到子模板,但是我 运行 遇到了两个错误。这些是我在主模板上的当前参数。

"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 时,它显示

"Template validation error: Template error: every Fn::Join object requires two parameters, (1) a string delimiter and (2) a list of strings to be joined or a function that returns a list of strings (such as Fn::GetAZs) to be joined."

当我不在主模板上使用 fn::join 时,错误是

Value of property Parameters must be an object with String (or simple type) properties

无论我是否fn::join子模板中的相同参数。

两个模板都可以在这里找到:https://github.com/slimg00dy/Troposphere-CloudformationTests

所以我之前的回答有点令人困惑 - 但我认为基本原理仍然成立。最后,当 CommaDelimitedList 在需要列表的参数中使用时,您不必 Join() 。我刚刚查看了您共享的存储库的最新更新,我认为您走在正确的轨道上。如果您需要更多帮助,请告诉我!

问题是在 CommaDelimitedList 上使用 Ref 时,您传递的是一个列表,因此它传递的是“[a,b,c]”而不是 "a,b,c"

所以在主模板上,我使用 Join(",") 传递列表,并使用 Join(" ") 传递字符串。这样它们就被引用为 "a,b,c" 和“ String”

在子模板上,我将参数设置为列表的 CommaDelimitedLists 和字符串中的字符串。这是因为它们从主模板传递的方式。

然后我在子模板上使用了 Ref,而没有在子模板上使用 Join()。这将 CommaDelimitedLists 创建到列表中,并将与 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 转换为列表,我使用 Join(",") 将它们保留为 CommaDelimitedLists 并将它们传递给子模板。

对于KeyPair String,我确保它在父模板上声明为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"

CommaDelimtedList只能解析一次,所以在parent模板中,需要设置type为"String",然后在child中 模板,像以前一样将其保留为 CommaDelimitedList。

问题出现了,因为 CloudFormation 正在解析父模板中的 CommaDelimitedList,然后尝试在子模板中再次解析它。