IfParam and conditions¶
A module can include or leave out resources based on the properties that the parent sets. There are two ways: the IfParam and IfNotParam metadata, and normal CloudFormation conditions.
IfParam and IfNotParam¶
Add Metadata.Rain.IfParam or Metadata.Rain.IfNotParam to a resource in a module:
IfParam: <Parameter>keeps the resource only when the parent sets that property.IfNotParam: <Parameter>keeps the resource only when the parent does not set that property.
cfnrain removes the IfParam and IfNotParam keys from the output. IfParam only works in modules.
Use IfParam for optional parts of a module, such as permissions for a resource that the parent passes in. Use IfNotParam when the parent can bring its own resource instead of the one that the module creates.
The module, queue-module.yaml:
Parameters:
DeadLetterArn:
Type: String
Resources:
Queue:
Type: AWS::SQS::Queue
Metadata:
Rain:
IfParam: DeadLetterArn
Properties:
RedrivePolicy:
deadLetterTargetArn: !Ref DeadLetterArn
maxReceiveCount: 5
SimpleQueue:
Type: AWS::SQS::Queue
Metadata:
Rain:
IfNotParam: DeadLetterArn
The parent template:
Modules:
Orders:
Source: ./queue-module.yaml
Properties:
DeadLetterArn: arn:aws:sqs:us-east-1:123456789012:orders-dlq
Events:
Source: ./queue-module.yaml
The packaged template:
Resources:
OrdersQueue:
Type: AWS::SQS::Queue
Properties:
RedrivePolicy:
deadLetterTargetArn: arn:aws:sqs:us-east-1:123456789012:orders-dlq
maxReceiveCount: 5
EventsSimpleQueue:
Type: AWS::SQS::Queue
Orders sets DeadLetterArn, so it gets Queue with a redrive policy. Events does not, so it gets SimpleQueue.
Conditions in modules¶
A module can have a Conditions section. cfnrain evaluates each condition when it packages the template:
- If the condition resolves to false, cfnrain removes the resources, modules and outputs that use it, and picks the false branch of each
Fn::If. - If the condition resolves to true, cfnrain keeps them and picks the true branch.
- cfnrain removes values that are
!Ref AWS::NoValue. - If cfnrain cannot resolve the condition, for example because it uses
AWS::Regionor a parameter of the parent template, it copies the condition to the parent template. The condition name gets the module name in front, like a logical ID.
Resolved conditions¶
The module:
Parameters:
Foo:
Type: String
Conditions:
Show0:
Fn::Equals:
- !Ref Foo
- bar
Show1:
Fn::And:
- Fn::Equals:
- !Ref Foo
- bar
- Condition: Show0
Show2:
Fn::Not:
- Fn::Or:
- Fn::Equals:
- !Ref Foo
- baz
- Fn::Equals:
- Fn::If:
- Fn::Equals:
- a
- a
- x
- y
- y
Resources:
Bucket0:
Type: AWS::S3::Bucket
Condition: Show0
Bucket1:
Type: AWS::S3::Bucket
Condition: Show1
Bucket2:
Type: AWS::S3::Bucket
Condition: Show2
The parent template:
Modules:
A:
Source: ./cond-intrinsics-module.yaml
Properties:
Foo: bar
B:
Source: ./cond-intrinsics-module.yaml
Properties:
Foo: baz
The packaged template. Module A has Foo: bar, so every condition is true. Module B has Foo: baz, so every condition is false and none of its buckets are in the output.
Resources:
ABucket0:
Type: AWS::S3::Bucket
ABucket1:
Type: AWS::S3::Bucket
ABucket2:
Type: AWS::S3::Bucket
Unresolved conditions¶
The parent template:
The module, cond-unres-module.yaml:
Parameters:
P:
Type: String
Conditions:
IsRegionUsEast1:
Fn::Equals:
- Ref: AWS::Region
- us-east-1
IsPTrue:
Fn::Equals:
- !Ref P
- true
Modules:
Sub:
Source: cond-unres-submodule.yaml
Properties:
P: !Ref P
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Condition: IsRegionUsEast1
A:
Type: A::B::C
Properties:
Name:
Fn::If:
- IsRegionUsEast1
- a-east
- a-not-east
C:
Type: D::E::F
Condition: IsPTrue
The submodule, cond-unres-submodule.yaml:
Parameters:
P:
Type: String
Conditions:
IsParam:
Fn::Equals:
- !Ref P
- true
Resources:
B:
Condition: IsParam
Type: A::B::C
The packaged template. The conditions depend on the region and on the parent parameter P, so they move to the parent with the prefixes Foo and FooSub.
Parameters:
P:
Type: String
Conditions:
FooIsRegionUsEast1:
Fn::Equals:
- Ref: AWS::Region
- us-east-1
FooIsPTrue:
Fn::Equals:
- !Ref P
- true
FooSubIsParam:
Fn::Equals:
- !Ref P
- true
Resources:
FooS3Bucket:
Type: AWS::S3::Bucket
Condition: FooIsRegionUsEast1
FooA:
Type: A::B::C
Properties:
Name:
Fn::If:
- FooIsRegionUsEast1
- a-east
- a-not-east
FooSubB:
Type: A::B::C
Condition: FooSubIsParam
FooC:
Type: D::E::F
Condition: FooIsPTrue