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

Json 尝试将参数从主模板传递到子模板,json,amazon-web-services,amazon-cloudformation,troposphere,Json,Amazon Web Services,Amazon Cloudformation,Troposphere,我试图将列表参数从主模板传递到子模板,但遇到两个错误。。这些是我在主模板上的当前参数 "Parameters": { "ELBSubnets": { "Default": "subnet-5d8fea67,subnet-3e35cf15", "Type": "CommaDelimitedList" }, "LCKeyPair": { "Default": "key-master", "Type": "Stri

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

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
在传递给子模板时,此方法正在同一模板上引用它们

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
在子模板上,它们被声明为完全相同

"Parameters": {
    "ELBSubnets": {
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Type": "String"
    },
    "LCSecurityGroups": {
        "Type": "CommaDelimitedList"
    }
},
它们在子模板的这个方法中被引用

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
这是模板的另一部分

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
当我尝试在主模板上使用fn::join时,它说

“模板验证错误:模板错误:每个Fn::Join对象都需要两个参数,(1)字符串分隔符,(2)要连接的字符串列表或返回要连接的字符串列表(如Fn::GetAZs)的函数。”

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

属性参数的值必须是具有字符串(或简单类型)属性的对象

不管我在子模板中是否有相同参数的fn::join

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }

这两个模板都可以在这里找到:

所以我之前的答案有点让人困惑——但我认为基本原理仍然有效。最后,当在需要列表的参数中使用CommaDelimitedList时,您不必将其加入()。我刚刚看了你最近对你分享的回购协议的更新,我认为你的思路是正确的。如果你需要更多的帮助,请告诉我

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

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

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

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
然后,我在子模板上使用了Ref,而在子模板上没有使用Join()。这将CommadeLimitedList创建为列表,并将通过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将CommadeLimitedList转换为列表,所以我使用Join(“”、“”)将它们保留为CommadeLimitedList,并将它们传递给子模板

至于KeyPair字符串,我确保它在父模板上声明为CommaDelimitedList,并使用Join(“”)连接,这实际上使它在引用子模板时成为一个字符串

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
在子模板上,它们是这样声明的

 "Parameters": {
    "ELBSubnets": {
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Type": "String"
    },
    "LCSecurityGroups": {
        "Type": "CommaDelimitedList"
    }
},
它们都是正常引用的,不需要在子模板上使用Join

"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }
有很多不同的方法可以做到这一点。我可以在子模板而不是父模板上进行连接。然而,我更喜欢保持一个模板复杂,其余尽可能干净。希望这能帮助其他人


我也应该能够将列表作为子模板上的列表传递,但是随后我收到错误“未知参数类型:列表”

CommadeLimitdList只能解析一次,因此在父模板中,需要将类型设置为“字符串”,然后在子模板中,和以前一样,将其保留为CommaDelimitedList


问题发生了,因为CloudFormation正在解析父模板中的CommaDelimitedList,然后又试图在子模板中再次解析它。

我已经照你说的做了。我已经删除了所有的“加入”,正如你所说的,它们是不需要的,这是我一开始的想法。然而,我再次得到“属性参数的值必须是具有字符串(或简单类型)属性的对象”。我已经在子模板和主模板上删除了它们。好的-这是在您尝试编译模板时发生的,还是在您尝试将其推入CloudFormation时发生的?对您的repo中的代码进行了一些快速测试,我可以看到模板编译得很好,所以这是一个带有CloudFormation的问题。给我一点时间,我会尝试复制一个我可以成功启动这些模板的环境,然后我会看看我是否能找出这里的问题。好的,我把它弄得有点乱,我已经让你克服了一些最初的问题-你可以在这里从你的来源看到我的差异:现在,它仍然失败,但这个错误更容易处理:模板错误:模板的“映射”部分中不存在名为“AMIMap”的映射。这是在创建子模板时完成的-您很可能只需要清理一些命名错误的值。记住——资源的名称和python对象的名称可以是不同的。请参阅我对您的KeyPair所做的更改。顺便说一句,“何时使用联接”位的关键是,当父级接受一个参数作为CommaDelimitedList时,它会将该参数转换为一个列表。当您将其传递给子级时,它将获得列表-但参数需要一个CommaDelimitedList,这是一个可以转换为列表的字符串-因此父级需要重新加入列表以传递它。这是非常令人困惑的,老实说,这是我停止使用嵌套堆栈的许多原因之一,相反,我尝试保持我的堆栈在CloudFormation方面是分开的,但是处理与代码的关系(比如stacker)。这对我来说是行得通的,但只有在创建两个新堆栈时(不使用模板S3URL指定的现有堆栈)和/或未在子模板上设置默认值时。可能需要将其作为bug提交给AWS。
"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"
                }
            },
            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },
            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },
            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },
Subnets": {
                "Ref": "ELBSubnets"
            }