Conditional attributes in Terraform

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.

Leave a Comment