Open zachzeid opened 8 years ago
Leaving this here, in case someone has time to test and add this to the examples:
from troposphere import Template, Parameter
t.add_metadata({
'AWS::CloudFormation::Interface': {
'ParameterGroups': [
{
'Label': {'default': 'AWS Configuration'},
'Parameters': ['AccountId']
},
],
'ParameterLabels': {
'AccountId': {'default': 'AWS Account Id'},
}
}
})
t.add_parameter(Parameter(
'AccountId',
Type='Number',
Default="000000000000",
Description="The AWS account id"
))
print(t.to_json())
IIRC, you can be a bit more clever by defining the parameter first and using paramter.title
instead of AccountId
.
I've confirmed this works, thanks!
I ended up creating a wrapper class for Template
that lets me define the group and label at the time the parameter is added to the template, e.g.:
domain_name = template.add_parameter(
Parameter(
"DomainName",
Description="The fully-qualified domain name for the application.",
Type="String",
),
group="Global",
label="Domain Name",
)
This way, I don't have to worry about keeping the interface and the overall template in sync. Adding the code for the Template
subclass below in case this is useful to anyone else and/or could be incorporated into Troposphere proper some day.
from collections import OrderedDict
from troposphere import Template
class InterfaceTemplate(Template):
"""
Custom Template class that allows us to optionally define groups and labels for
CloudFormation Parameters at the time they're added to the template. Groups and
labels specified, if any, will be added to a custom AWS::CloudFormation::Interface
"""
def __init__(self, *args, **kwargs):
super(InterfaceTemplate, self).__init__(*args, **kwargs)
# use OrderedDict() so we can keep track of the order in which groups are added
self.parameter_groups = OrderedDict()
self.parameter_labels = {}
self.group_order = []
def add_parameter(self, parameter, group=None, label=None):
"""
Save group and/or label, if specified, for later generation of
'AWS::CloudFormation::Interface' in to_dict().
"""
parameter = super(InterfaceTemplate, self).add_parameter(parameter)
if group:
if group not in self.parameter_groups:
self.parameter_groups[group] = []
self.parameter_groups[group].append(parameter.title)
if label:
self.parameter_labels[parameter.title] = label
return parameter
def set_group_order(self, group_order):
"""
Set an ordered list of all known, possible parameter groups in this stack.
If none is provided, groups will appear in the order they were first passed
to add_parameter().
"""
self.group_order = group_order
def to_dict(self):
"""
Overwrite 'AWS::CloudFormation::Interface' key in self.metadata (if any)
with the groups and labels defined via add_parameter(), and then call
super().to_dict().
"""
# create an ordered list of parameter groups for our interface
ordered_groups = list(self.group_order)
groups_in_stack = list(self.parameter_groups.keys())
# add any groups specified in the stack that we didn't know about in advance
ordered_groups += [g for g in groups_in_stack if g not in ordered_groups]
# remove any groups NOT specified in the stack
ordered_groups = [g for g in ordered_groups if g in groups_in_stack]
# update metadata with our interface
self.metadata.update({
'AWS::CloudFormation::Interface': {
'ParameterGroups': [
{
'Label': {'default': group},
'Parameters': self.parameter_groups[group],
}
for group in ordered_groups
],
'ParameterLabels': dict([
(parameter, {'default': label})
for parameter, label in self.parameter_labels.items()
]),
}
})
return super(InterfaceTemplate, self).to_dict()
Would be nice to see if Troposphere supports this, in particular the AWS::CloudFormation::Interface functionality in CloudFormation.