Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to pass parameters from Master to child template

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

like image 565
Mo Ali Avatar asked May 23 '15 02:05

Mo Ali


People also ask

Is it possible to pass parameter value in child component?

Abhinav Sharma. We are able to pass the parameter value in child component, but my requirement is to get the value in JS controller of Child component under init. Like we have Account drop down list im our parent component and on change of Account from dropdown get all the associate contacts in the child component.

Can the environment parameter be passed from master to nested templates?

Because the environment parameter is a common denominator across all the nested templates, it is natural to think that the parameter can be passed from master to nested ones. How can we work this out then?

Why can’t I use both parameterslink and parameters at the same time?

We can’t use both parametersLink and parameters at the same time. We have to use one or the other. This is by design at the time of this writing. Because the environment parameter is a common denominator across all the nested templates, it is natural to think that the parameter can be passed from master to nested ones.

How to add common parameters to an Azure Storage template?

Add the common parameters to each parameter JSON file and upload it to Azure Storage Account programatically. Create a set of parameter files for all possible combinations. Use something to refer during the template deployment, whose value will be changing over time during the deployment but the reference point remains the same.


1 Answers

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"

like image 57
Mo Ali Avatar answered Oct 15 '22 02:10

Mo Ali