Does Terraform support conditional attributes? I only want to use an attribute depending on a variable's value.
Example:
resource "aws_ebs_volume" "my_volume" { availability_zone = "xyz" size = 30 if ${var.staging_mode} == true: snapshot_id = "a_specific_snapshot_id" endif }
The above if
statement enclosing the attribute snapshot_id
is what I'm looking for. Does Terraform support such attribute inclusion based on a variable's value.
Terraform doesn't support if-statements, so this code won't work. However, you can accomplish the same thing by using the count parameter and taking advantage of two properties: If you set count to 1 on a resource, you get one copy of that resource; if you set count to 0, that resource is not created at all.
Attribute. In Terraform's configuration language: a named piece of data that belongs to some kind of object. The value of an attribute can be referenced in expressions using a dot-separated notation, like aws_instance.example.id .
When count is set, Terraform distinguishes between the block itself and the multiple resource or module instances associated with it. Instances are identified by an index number, starting with 0 . <TYPE>. <NAME> or module.
Maps are a collection of string keys and string values. These can be useful for selecting values based on predefined parameters such as the server configuration by the monthly price.
Terraform 0.12 (yet to be released) will also bring support for HCL2 which allows you to use nullable arguments with something like this:
resource "aws_ebs_volume" "my_volume" { availability_zone = "xyz" size = 30 snapshot_id = var.staging_mode ? local.a_specific_snapshot_id : null }
Nullable arguments are covered in this 0.12 preview guide.
For version of Terraform before 0.12, Markus's answer is probably your best bet although I'd be more explicit with the count
with something like this:
resource "aws_ebs_volume" "staging_volume" { count = "${var.staging_mode ? 1 : 0}" availability_zone = "xyz" size = 30 snapshot_id = "a_specific_snapshot_id" } resource "aws_ebs_volume" "non_staging_volume" { count = "${var.staging_mode ? 0 : 1}" availability_zone = "xyz" size = 30 }
Note that the resource names must be unique or Terraform will complain. This then causes issues if you need to refer to the EBS volume such as with an aws_volume_attachment
as in pre 0.12 the ternary expression is not lazy so something like this doesn't work:
resource "aws_volume_attachment" "ebs_att" { device_name = "/dev/sdh" volume_id = "${var.staging_mode ? aws_ebs_volume.staging_volume.id : aws_ebs_volume.non_staging_volume.id}" instance_id = "${aws_instance.web.id}" }
Because it will attempt to evaluate both sides of the ternary where only one can be valid at any point. In Terraform 0.12 this will no longer be the case but obviously you could solve it more easily with the nullable arguments.
I'm not aware of such a feature, however, you can model around this, if your cases are not too complicated. Since the Boolean values true
and false
are considered to be 1
and 0
, you can use them within a count. So you may use
provider "null" {} resource "null_resource" "test1" { count= ${var.condition ? 1 : 0} } resource "null_resource" "test2" { count = ${var.condition ? 0 : 1} } output "out" { value = "${var.condition ? join(",",null_resource.test1.*.id) : join(",",null_resource.test2.*.id) }" }
Only one of the two resources is created due to the count
attribute.
You have to use join
for the values, because this seems to handle the inexistence of one of the two values gracefully.
Thanks ydaetskcor for pointing out in their answer the improvements for variable handling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With