A Terraform equivalent to CloudFormations AWS::NoValue ?
Sometimes, when using an infrastructure as code tool like Terraform or CloudFormation,
you only want to include a property on a resource under certain
conditions, while always including the resource itself. In AWS CloudFormation there are a few
CloudFormation Conditional Patterns
that let you do this, but and this is the central point of this post,
what’s the Terraform equivalent of using AWS::NoValue to remove a property?
Here’s an example of doing this in CloudFormation. If InProd is false
the Iops property is completely removed from the resource. Not set to undef, no
NULLs, simply not included at all.
"MySQL" : {
"Type" : "AWS::RDS::DBInstance",
"DeletionPolicy" : "Snapshot",
"Properties" : {
... snip ...
"Iops" : {
"Fn::If" : [ "InProd",
"1000",
{ "Ref" : "AWS::NoValue" }
]
}
... snip ...
}
}While Terraform allows you to use the, um, ‘inventive’, count meta-parameter
to control if an entire resource is present or not -
resource "aws_security_group_rule" "example" {
count = "${var.create_rule}"
... snip ...
}
It doesn’t seem to have anything more fine grained.
One example of when I’d want to use this is writing an RDS module. I want
nearly all the resource properties to be present every time I use
the module, but not all of them. I’d only want replicate_source_db or
snapshot_identifier to be present when a certain variable was passed in.
Here’s a horrific example of what I mean
resource "aws_db_instance" "default" {
... snip ...
# these properties are always present
storage_type = "gp2"
parameter_group_name = "default.mysql5.6"
# and then the optional one
replicate_source_db = "${var.replication_primary | absent_if_null}"
... snip ...
}
But with a nice syntax rather than that horrible made up one above. Does
anyone know how to do this? Do I need to write either two nearly
identical modules, with one param different or slightly better, have two
database resources, one with the extra parameter present and use a
count to choose one of those? Help me Obi-internet! Is these a better way to
do this?