cloudtools / cloudtools/troposphere

mutually_exclusive and exactly_one aren't clever enough to deal with AWS::NoValue

Open
#778 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
4.9k
Forks
1.4k
PR merge metrics
No merged PRs in 30d

Description

So as part of #765 I was asked to add some validations to `AWS::EC2::Route`, which makes sense, however it turns out this validation is too naïve to deal with a property being set, and it's value is either `Ref('AWS::NoValue')` or an even more complex scenario inside a conditional where one of the possible values **might** be `Ref('AWS::NoValue')`. Such things appear to be perfectly legitimate in CloudFormation because if the property has no value, then CloudFormation will simply ignore it after its conditionals have been satisfied.

For a real world example of why one might need this, consider a stack that configures a VPC, and in setting up the Routes also needs to set up NAT, but the value of some property may determine if the stack creates a NAT Gateway, or NAT instances. Inside the Route object you may need something like:

```python
Route(
'Route66',
DestinationCidrBlock='0.0.0.0/0',
RouteTableId=Ref('RouteTable66'),
InstanceId=If(
'UseNat',
Ref('AWS::NoValue'),
Ref('UseNat')
),
NatGatewayId=If(
'UseNat',
Ref('UseNat'),
Ref('AWS::NoValue')
)
)
```

I see a few potential options to solve this:
* Rip out the validation from `AWS::EC2::Route`. This is the simplest but makes foot-gunning easier, not harder.
* Extend the validation in mutually_exclusive to not count properties that have either `Ref('AWS::NoValue')` or any type of conditional that has at least one outcome value as `Ref('AWS::NoValue')`. This would add complexity, and it would still remain somewhat non-deterministic if the correct value would be applied.
* Some other option my non-caffienated brain has yet to conjur up.

Contributor guide

Open the contributing guide

Research direction

Start with the validation behavior in mutually_exclusive and exactly_one, then inspect the AWS::EC2::Route validations added in the context of #765. Clarify the expected treatment of Ref('AWS::NoValue') and conditional outcomes before deciding on a change; done means the agreed behavior is covered by regression tests without weakening ordinary validation.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
cloud
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.