Trying to pass parameters from Master to child tem

2020-08-11 10:46发布

I'm trying to pass list parameters from master to child template, however I'm running into two errors.. These are my current parameters on the master template.

"Parameters": {
    "ELBSubnets": {
        "Default": "subnet-5d8fea67,subnet-3e35cf15",
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Default": "key-master",
        "Type": "String"
    },
    "LCSecurityGroups": {
        "Default": "sg-10a15c74,sg-880e5fec",
        "Type": "CommaDelimitedList"
    }
},

They are being referenced in this method on the same template when passing on to the child template.

    "ChildTempate1": {
        "Properties": {
            "Parameters": {
                "ELBSubnets": {
                    "Ref": "ELBSubnets"
                },
                "KeyPair": {
                    "Ref": "LCKeyPair"
                },
                "LCSecurityGroups": {
                    "Ref": "LCSecurityGroups"
                }
            },

On the child template, they are declared exactly the same.

"Parameters": {
    "ELBSubnets": {
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Type": "String"
    },
    "LCSecurityGroups": {
        "Type": "CommaDelimitedList"
    }
},

And they're being referenced in this method in the child template.

            "KeyName": {
                "Ref": "LCKeyPair"
            },
            "SecurityGroups": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                ]
            }
        },

This is another part of the template.

            "Subnets": {
                "Fn::Join": [
                    ",",
                    [
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                ]
            }
        },

When I attempt to use the fn::join on the master template, it says

"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."

When I don't use fn::join on the master template the error is

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

Regardless of whether I have fn::join on the same parameters in the child template.

Both templates can be found here: https://github.com/slimg00dy/Troposphere-CloudformationTests

3条回答
放我归山
2楼-- · 2020-08-11 11:06

So my previous answer was a little confusing - but I think the basics still stand. In the end you shouldn't have to Join() a CommaDelimitedList when it is used in an argument that expects a list. I just looked at your most recent updates to the repo you shared, and I think you're on the right track. If you need more help, let me know!

查看更多
地球回转人心会变
3楼-- · 2020-08-11 11:14

CommaDelimtedList can only be parsed once, so in the parent template, you need to set the type as "String", then in the child template, keep it as CommaDelimitedList, as before.

The problem is happening, because CloudFormation is parsing the CommaDelimitedList in the parent template, and then it's trying to parse it again in the child template.

查看更多
【Aperson】
4楼-- · 2020-08-11 11:17

The issue is that when using Ref on a CommaDelimitedList, you pass a list, so it passes "[a,b,c]" rather than "a,b,c"

So on the master template I've used Join(",") to pass lists, and Join(" ") to pass strings. This way they're Referenced as "a,b,c" and " String"

On the child template I've set the parameters as CommaDelimitedLists for the lists and String from the String. This is because of the way they're being passed from the master template.

I then used Ref on the Child template without the use of Join() on the child template. This created the CommaDelimitedLists into Lists and the Strings that were joined with Join(" ") passed as strings.

Here is my parameter declaration on the master Template.

"Parameters": {
    "ELBSubnets": {
        "Default": "subnet-5d8fea67,subnet-3e35cf15",
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Default": "key-master",
        "Type": "CommaDelimitedList"
    },
    "LCSecurityGroups": {
        "Default": "sg-10a15c74,sg-880e5fec",
        "Type": "CommaDelimitedList"
    }
},

Here is how I used Join(","), Join(" ") and Ref. Since Ref converts the CommaDelimitedLists into Lists, I used Join(",") to keep them as CommaDelimitedLists and pass them on to the child template.

As for the KeyPair String, I made sure that it was declared as a CommaDelimitedList on the parent template and joined with Join(" "), this effectively made it into a string when referencing to the child template.

            "Parameters": {
                "ELBSubnets": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "ELBSubnets"
                        }
                    ]
                },
                "LCKeyPair": {
                    "Fn::Join": [
                        " ",
                        {
                            "Ref": "LCKeyPair"
                        }
                    ]
                },
                "LCSecurityGroups": {
                    "Fn::Join": [
                        ",",
                        {
                            "Ref": "LCSecurityGroups"
                        }
                    ]
                }
            },

On the child template, they're declared like so.

 "Parameters": {
    "ELBSubnets": {
        "Type": "CommaDelimitedList"
    },
    "LCKeyPair": {
        "Type": "String"
    },
    "LCSecurityGroups": {
        "Type": "CommaDelimitedList"
    }
},

And they are all referenced normally without the use of Join on the child template.

Subnets": {
                "Ref": "ELBSubnets"
            }

There could have been many different ways to do this. I could have had the joins on the child template rather than the parent template. However I prefer to keep one template complicated and the rest as clean as possible. Hope this helps others down the line.

I also should have been able to pass the list as a list on the child template, however then I received the error "Unknown parameter type: List"

查看更多
登录 后发表回答