Many CloudFormation resources take parameters whose values are lists. Like tags on a Load Balancer:
Lb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: MyLb Scheme: internal Subnets: !Ref Subnets Tags: - Key: TagA Value: Unconditionally present
I often find that I want to add an item to the list, but only if a condition is true. That’s possible, but the syntax is a little funky.
In addition to conditions, we need
AWS::NoValue. It’s a CloudFormation “Pseudo Parameter” that removes properties from templates. It allows you to dynamically include or remove properties based on conditions; you can pass
AWS::NoValue to either the true or false case of the condition and it’s as if you never wrote that property into the template. The docs demonstrate it for top-level properties like
Scheme, but it also works for list items:
Conditions: AlwaysTrue: !Equals [true, true] AlwaysFalse: !Equals [true, false] Resources: Lb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: MyLb Scheme: internal Subnets: !Ref Subnets Tags: - Key: TagA Value: Unconditionally present - !If - AlwaysTrue - Key: TagB Value: Always present - !Ref 'AWS::NoValue' - !If - AlwaysFalse - Key: TagC Value: Never present - !Ref 'AWS::NoValue'
These conditions (which of course are hacks just to make the demo easy) will only create
Before we wrap up, though, it’s worth highlighting a detail. There are two list here, the list of tags and the list of arguments to the
- !If - AlwaysFalse - Key: TagC Value: Never present - !Ref 'AWS::NoValue'
The second element of the arguments list (line 3) is a map that will become the value of an element of the tags list (line 1). In long templates with complicated conditions I find this detail turns in to a tripping point. If you’re getting errors, make sure your indentation is clean and you’re not mixing up the two lists.
Need more than just this article? I’m available to consult.
You might also want to check out these related articles: