cfn-language-discussion
cfn-language-discussion copied to clipboard
Map Parameter Type
Given the 60 parameter template limit, structured parameters are a way to overcome this limitation. Example:
Parameters:
LogGroupInfo:
Type: Map
...
Resources
...
CloudWatchLogsGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !GetAtt LogGroupInfo.Name
RetentionInDays: !GetAtt LogGroupInfo.RetentionInDays
...
Would simply raising the parameter limit be better? Raising that limit is currently being investigated
I don't see this as a workaround; resources have structured parameters, and with nested stacks, stacks can be resources, so they should also have structured parameters.
Additionally, a Map parameter type would help organize the stack parameter space. Traditionally, the example above would be implemented using two parameters, and some form of parameter prefix convention would be used to organize the names to indicate that they are related to the same resource. This imposes additional cognitive burden on humans, especially when many parameters are present. The same issue applies to outputs - instead of multiple related outputs, a single structured output could be used.
Got it. There's also AWS::CloudFormation::Interface
which can help organize stack parameters a bit if using the console to input parameter values if that helps your use-case at all
I'm aware of AWS::CloudFormation::Interface
, but our use case has hundreds of CloudFormation stacks per deployment and is largely driven by extensive custom automation code. And because we are running into the 60-parameter limit, we had to resort to using parameter stacks just for the purpose of working around that limit. We do use the CloudFormation console, but mostly for debugging. For reasons stated above, with 700+ parameters per deployment, a Map-type parameter would help us organize this better.
I think raising the parameter limit would certainly be something that would help in @josb's use case, but I would say that even without that scenario the overall CloudFormation developer community stands to benefit greatly from a hash/dictionary parameter type.
As an example, for a stack that perhaps creates two AWS::EC2::Instances
, quite often I find myself generating parameters like this:
- Instance1Type
- Instance1VolumeSize
- Instance1SecurityGroup
- Instance2Type
- Instance2VolumeSize
- Instance2SecurityGroup
And if I suddenly need to make a 3rd instance as part of the stack or perhaps need a 4th parameter then that suddenly adds a lot more parameters.
With a hash/dict parameter type, even though I'd be passing the same amount of information, it would be a whole lot cleaner and easier to read and understand.
A workaround that has worked for me is using the PyPlate CloudFormation macro. Create the macro first by creating a CF stack using that template.
First, create a CommaDelimitedList parameter in your template:
Transform: [PyPlate]
Parameters:
AutoScalingContainerCountRange:
Description: The min and max number of containers
Type: CommaDelimitedList
Default: MinCapacity=2,MaxCapacity=5
Then, in your template, you can reference Python code to do parsing. I loop through the list and split it by "=" to separate key and value:
Resources:
AutoScalingTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: |
#!PyPlate
autoscale_range_dict = {}
for alarm_param in params['AutoScalingContainerCountRange']:
condition,value = alarm_param.split('=')
autoscale_range_dict[condition] = value
output = int(autoscale_range_dict['MinCapacity'])
This is not the most elegant solution since I had to use a macro. But it allows me to create key-value pairs like MinCapacity=2,MaxCapacity=5
. I still support this feature request though! Adding a "Hash" parameter would make my templates cleaner since I don't have to add Python code inside my templates.
How about you guys, how did you work around this?
Thanks for sharing this, @jamby1100. We have similar macros that operate on CommaDelimitedLists, including the use of inline Ruby ERB templating. And surely others have come up with similar solutions as workarounds. But they increase cognitive load for people dealing with the code, and add to the maintenance burden. A centralized solution offered by AWS would avoid all these duplicative efforts.
Changed from Hash
to Map
as the latter is what YAML calls this key-value data structure.
@josb Thank you very much for your feedback! Since this repository is focused on resource coverage, I'm transferring this issue over to a new GitHub repository dedicated to CloudFormation template language issues.
Is this one going anywhere? I could certainly use this.