Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional attributes in Terraform

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.

like image 246
Basil Musa Avatar asked Jul 24 '18 10:07

Basil Musa


People also ask

How do you use if condition in Terraform?

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.

What are attributes in Terraform?

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 .

What is Count Index Terraform?

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.

What is map type in Terraform?

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.


2 Answers

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.

like image 69
ydaetskcoR Avatar answered Sep 29 '22 17:09

ydaetskcoR


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.

like image 29
Markus Avatar answered Sep 29 '22 19:09

Markus