aws-cloudformation / aws-cloudformation/cfn-language-discussion
"optional" parameters
- Dominant language
- No language data
- Stars
- 147
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
### Community Note
* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment
### **Tell us about your request**
Allow a parameter, _regardless of type_, to truly be "optional" - meaning stack processes don't fail when they are unset.
### **Tell us about the problem you are trying to solve. What are you trying to do, and why is it hard?**
I find myself commonly using a paradigm where I want to create resources (or not), or specify a resource property (or not), based on whether a parameter is defined.
As you probably already know, and can see below, this is usually do-able via a parameter of type `String`, and a condition testing for emptiness of that string. But this approach doesn't work when the parameter really should be of a different type than `String` (example below), and so I figure that rather than "simulating" an optional parameter, it would be preferable to have true support for it, that would work with any parameter type.
### **Are you currently working around this issue?**
For parameters of type `String`, you can effect what I'm describing by (1) setting the `Default` value to an empty string, (2) creating a condition that evaluates the Parameter value for a match against an empty string, and (3) use that condition to control whether a resource is created, or as the condition for an `!If` intrinsic function, typically using `AWS::NoValue` when the parameter value is empty, to control whether a resource property is set.
This approach does NOT seem to work for [AWS-specific parameter types](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-specific-parameter-types). The below exhibits a scenario where I'd like to use `AWS::EC2::Image::Id` as the parameter type, but instead have to use type `String` ...
```YAML
Parameters:
InstanceAmi:
Type: String
Default: ''
InstanceAmiAlias:
Type: AWS::SSM::Parameter::Value
AllowedValues:
- /aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-x86_64-ebs
- /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
Conditions:
HasSpecifiedInstanceAmi: !Not [!Equals ['', !Ref InstanceAmi]]
Resources:
BastionHost:
Type: AWS::EC2::Instance
Properties:
ImageId: !If [HasSpecifiedInstanceAmi, !Ref InstanceAmi, !Ref InstanceAmiAlias]
```
### **What is the expect behavior with this new feature**
I'm not sure I have the optimal conception of this in mind, but I imagine it implemented such that ...
* When specifying a parameter, I can indicate whether it's acceptable for that parameter to be unset, via a new attribute - something like `optional: Boolean` - that when unspecified, defaults to `false`.
* When `optional: false`, CFN would object to the respective parameter being unset - just as it currently does for all parameters.
* When `optional: true`, CFN would NOT object to the respective parameter being unset, and the template author has to handle the case in which it's unset.
* Perhaps I need to validate whether a parameter is unset (undefined) via a condition, which I can then use with an `!If` to handle both cases - the parameter being set or unset.
* Perhaps a condition isn't needed, because there's some new intrinsic function like `!IsDefined` that operates in a fashion similar to `!If`. It takes 3 arguments - the name of a parameter, and then what to do if the parameter is set, and not.
The example above, using an implementation like I describe might look something like ...
```YAML
Parameters:
InstanceAmi:
Type: AWS::EC2::Image::Id
Optional: true
InstanceAmiAlias:
Type: AWS::SSM::Parameter::Value
AllowedValues:
- /aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-x86_64-ebs
- /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
Resources:
BastionHost:
Type: AWS::EC2::Instance
Properties:
ImageId: !IsDefined [!Ref InstanceAmi, !Ref InstanceAmi, !Ref InstanceAmiAlias]
```
Contributor guide
Research direction
Start by reviewing the Parameters, Conditions, and Resources sections in the issue examples, along with the existing !Ref and !If intrinsic-function behavior. A complete change would let non-String parameters remain unset when explicitly optional, preserve required-parameter validation, and provide a documented way to handle the unset case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100