aws-cloudformation / aws-cloudformation/cfn-language-discussion

"optional" parameters

Open
#116 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.