Conditional attributes in Terraform

Basil Musa picture Basil Musa · Jul 24, 2018 · Viewed 19.9k times · Source

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.

Answer

ydaetskcoR picture ydaetskcoR · Jul 24, 2018

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       = "staging_mode ? a_specific_snapshot_id : null"
}

Nullable arguments are covered in this 0.12 preview guide.

For now, pre 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.