Reputation: 6208
I have two different lists list_a
and list_b
and I want to choose between them based on a value local.server
I've tried this and it doesn't work
locals {
server = "ubuntu"
list_a = "${list("aaa")}"
list_b = "${list("bbb")}"
chosen = "${local.server == "ubuntu" ? local.list_a : local.list_b}"
}
output "chosen" {
value = "${local.chosen}"
}
Error: Error asking for user input: 1 error(s) occurred:
* local.chosen: local.chosen: At column 3, line 1: conditional operator cannot be used with list values in:
${local.server == "ubuntu" ? local.list_a : local.list_b}
Upvotes: 3
Views: 10783
Reputation: 151
There is a nice workaround for those still using terraform < 0.12.x:
You can use split to create a string from a list, evaluate ternary then join to make it a list again.
a = ["list", "values", "for ubuntu"]
b = ["list", "values", "for others"]
new_list = "${split(",", local.server == "ubuntu" ? join(",", local.a) : join(",", local.b))}"
Upvotes: 1
Reputation: 6208
Interpolation only seems to work on strings so if we make the ternary expression return a string by joining an often unused character i.e. |
delim = "|"
chosen = "${local.server == "ubuntu" ?
join(local.delim, local.list_a) :
join(local.delim, local.list_b)}"
and then we can change the output to split on that same delimiter
output "chosen" {
value = "${split(local.delim, local.chosen)}"
}
✗ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
chosen = [
aaa
]
Upvotes: 2
Reputation: 74249
In Terraform v0.11, the conditional operator works only with primitive-typed values (strings, numbers, booleans). You can work around this by constructing a map with the two options and then conditionally choosing a key, as opposed to conditionally choosing a value:
locals {
lists = {
a = "${list("aaa")}"
b = "${list("bbb")}"
}
}
output "chosen" {
value = "${local.lists[local.server == "ubuntu" ? "a" : "b"]}"
}
In the forthcoming (at the time of writing) Terraform v0.12 release, the conditional operator works with values of any type, as long as both the true and false expressions can be converted to the same type during type checking, so your original example would work but can be rewritten using the first-class expression syntax also introduced by v0.12:
locals {
server = "ubuntu"
list_a = ["aaa"]
list_b = ["bbb"]
chosen = local.server == "ubuntu" ? local.list_a : local.list_b
}
output "chosen" {
value = local.chosen
}
Upvotes: 7