Reputation: 123
I'm using map variables and the lookup function to configure aws differently depending on the workspace selected. It works fine when the variable contains string but I can't get it to work with arrays and I'm not sure if it's possible
I've poured over the terraform documentation but can't see to sort it out. It looks like it can't be down with a map of arrays. Maybe someone has sorted through this issue
variable "cidr" {
type = "map"
default = {
"prod" = ["10.7.3.0/24","10.7.4.0/24"]
"test" = ["10.8.3.0/24","10.8.4.0/24"]
}
}
cidr = ${lookup(var.cidr, terraform.workspace)}"
lookup() can only be used with maps of primitive types.
Upvotes: 4
Views: 13476
Reputation: 74249
If you are using Terraform v0.12.0 or later, the idiomatic way to access one of the lists from your map of lists is to use the index syntax:
cidr = var.cidr[terraform.workspace]
You can also use the index syntax in Terraform v0.11 or earlier, but it must be wrapped in a template string because that is how we indicate to Terraform that we intend to use an expression in those older versions:
cidr = "${var.cidr[terraform.workspace]}"
The lookup
function is for situations where you don't know if the given key is present and want to provide a default value to use instead if it is not. Although lookup
with only two arguments is still supported for backward-compatibillity, it should generally be used only in its three-argument form in modern Terraform:
# (this particular default is likely not a good idea, but this
# is just to illustrate the syntax.)
cidr = lookup(var.cidr, terraform.workspace, ["0.0.0.0/0"])
Until Terraform 0.12.7, the lookup
function is indeed restricted to only work with maps of primitive types. In Terraform 0.12.7 it was generalized to behave the same way as the index operator, but with the extra rule of returning the default value if the requested key isn't present.
As a side note, if you are using Terraform v0.12.0 or later then you can provide a more specific type constraint on that variable:
variable "cidr" {
type = map(list(string))
default = {
"prod" = ["10.7.3.0/24","10.7.4.0/24"]
"test" = ["10.8.3.0/24","10.8.4.0/24"]
}
}
By telling Terraform exactly what element types are expected for the list and map type, Terraform can automatically check the value provided by the caller to make sure it conforms, and report a type error if not. If you just write "map"
then that's a legacy shorthand for map(any)
, in which case Terraform can only check that it's a map of any single type, not specifically what the element type must be. I'd recommend always using exact type constraints in Terraform 0.12.0 or later.
Upvotes: 4