Reputation: 153
This is a bit hard to describe. So I have a map that looks like this after I've simplified it for clarity:
server_ip_configs = {
mgmt = {
ct = "1"
}
applicationgateway = {
ct = "1"
}
monitor = {
ct = "1"
}
app = {
ct = "3"
}
}
What I want to do is iterate over the map to create a flat list where elements are multiplied by the number of the ct property into a new flat list. So we end up with a list that looks a bit like this:
server_ip_configs_mapped = [
{
name = "mgmt-1"
}
{
name = "applicationgateway-1"
}
{
name = "monitor-1"
}
{
name = "app-1"
}
{
name = "app-2"
}
{
name = "app-3"
}
]
Creating a list of elements for each row explicitly by setting a variable is trivial:
data "null_data_source" "server_list_ip_configs" {
count = lookup(var.server_ip_configs[var.server_role], "ct", 0)
inputs = {
name = "${var.server_role}-${count.index +1}"
}
}
I can put this in a module and call multiple instances of the module and concat the results. But this is not a nice way to do it and not at all DRY. Am I right in thinking there is no other way of doing this in Terraform? Is it because terraform is essentially declarative and maybe I should declare a list with multiple instance in it rather than try and generate one? Using a for loop won't work because you cant use an integer to iterate over explicitly from what I can see. So no:
for i in 5
Any answers to this welcome. Thanks.
Upvotes: 3
Views: 6763
Reputation: 17664
Terraform 0.12 introduced for loops, you can do something like:
variable "server_ip_configs" {
default = {
mgmt = { ct = "1" }
applicationgateway = { ct = "1" }
monitor = { ct = "1" }
app = { ct = "3" }
}
}
output "myout" {
value = [for k, v in var.server_ip_configs : { "name" = join("-", [k, v.ct]) }]
}
Here the terraform output of that
terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
myout = [
{
"name" = "app-3"
},
{
"name" = "applicationgateway-1"
},
{
"name" = "mgmt-1"
},
{
"name" = "monitor-1"
},
]
Upvotes: 0
Reputation: 501
@Helder came close, but I interpreted the request slightly different. Your intentions are to build the list based on the ct value, which looks like a count. This should be what you are looking for. Notice the use of range()
to do what you were looking in regard to the for i in 5
statement.
variable "server_ip_configs" {
default = {
mgmt = { ct = "1" }
applicationgateway = { ct = "1" }
monitor = { ct = "1" }
app = { ct = "3" }
}
}
locals {
server_ip_configs_mapped = flatten([
for server, count in var.server_ip_configs : [
for i in range(count.ct) : {
"name" = join("-", [server, i+1])
}
]
])
}
output server_ip_configs_mapped { value = local.server_ip_configs_mapped }
Output:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
server_ip_configs_mapped = [
{
"name" = "app-1"
},
{
"name" = "app-2"
},
{
"name" = "app-3"
},
{
"name" = "applicationgateway-1"
},
{
"name" = "mgmt-1"
},
{
"name" = "monitor-1"
},
]
Upvotes: 5