21

I have a list in terraform that looks something like:

array = ["a","b","c"]

Within this terraform file there are two variables called age and gender, and I want to make it so that the list called array has an extra element called "d" if age is equal to 12 and gender is equal to male (i.e. if var.age == 12 && var.gender == 'male' then array should be ["a","b","c","d"], else array should be ["a","b","c"]). Would the following going along the right path, or would I need to use another method?

array = ["a","b","c", var.age == 12 && var.gender == 'male' ? "d" : null]
Sabo Boz
  • 1,683
  • 4
  • 13
  • 29

3 Answers3

30

There is another way to do that using flatten:

variable = flatten(["a", "b", "c", var.age == 12 ? ["d"] : []])
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
desunit
  • 847
  • 8
  • 12
8

There are few ways you could do it. One way would be (example):

variable "array" {
  default = ["a","b","c"]
}

variable "age" {
  default = 12
}

variable "gender" {
  default = "male"
}

locals {
  array = var.age == 12 && var.gender == "male" ? concat(var.array, ["d"]) : var.array
}

output "test" {
  value = local.array
}
Marcin
  • 215,873
  • 14
  • 235
  • 294
3

Another approach to the problem in your particular example is removing empty elements at the end of the array.

compact is perhaps the most straightforward, but requires you to rely on using "" as a sentinel value for Emptiness.

From the documentation:

compact takes a list of strings and returns a new list with any empty string elements removed.

> compact(["a", "", "b", "c"])
[
  "a",
  "b",
  "c",
]

I would prefer this over the other answers because it's more idiomatic. I suppose it only works for strings though.

array = compact(["a","b","c", var.age == 12 && var.gender == 'male' ? "d" : ""])`
["a","b","c"] if age != 12 and gender != male
["a","b","c", "d"] if age == 12 and gender == male

Of course the "" element could be anywhere in your list and compact would handle this optionality issue.


I would also be interested in which has the best O() performance. I don't know how compact is implemented underneath the hood, but in general you would either copy elements into a new array or you would be shifting elements into gaps left by removed elements.

I don't expect any other solution to be much better than this. Perhaps concat.

Given that, it probably requires O(n) comparisons + appends, and then takes O(n) space because a new list is created.

Breedly
  • 12,838
  • 13
  • 59
  • 83