Combine values from tuples

I have this:

locals {
  all = [
    {
      "ip" = [
        "192.168.211.189",
      ]
      "name" = [
       "ubutest0",
       ]
    },
   {
      "ip" = [
         "192.168.211.211",
       ]
      "name" = [
         "ubutest1",
     ]
    },
  ]
}

How can I have output formatted like this?:

ubutest0:  192.168.211.189
ubutest1: 192.168.211.211

What I mean here is that I don’t know how many values there will be, so I need to loop trough, not like this "${local.all[0].name[0]}: ${local.all[0].ip[0]}"

Hi @jouros , it would be really helpful if the code would be properly formatted within triple backticks.

Do you care about multiple IPs or is it only a single IP always?

Hi @jouros,

I think you’ll find what you’re looking for in the String Templates documentation. There’s a similar sort of example in the documentation for the for directive.

<<EOT
%{ for ip in aws_instance.example.*.private_ip }
server ${ip}
%{ endfor }
EOT

Hi!
VM can have multiple IP addresses.

Yes, thanks, that String Template looks very promising for my case, I’ll give it a try.

Hi!
IP address is object and it gives error that object can not be converted to string? I tried this way:

convert = <<-EOT
%{ for k,v in local.all ~}
${k} : ${v}
%{ endfor ~}

Any ideas how can I convert object to string?

I also tried to test nested for loops like this:

output "test"
  value = [ for i,v in local.all : ${i} ${tostring(flatten([ for key, val in local.all[*].ip : v]))}"
}

But I can not get that work :frowning:

Hi @jouros,

From your data structure above, it seems like you need to take nested values from the object rather than just “turn the object into a string”.

In that for expression you wrote, v is the current object from the list, and so e.g. v.name would refer to the list of names.

It isn’t clear to me why there is a list of names and a list of IP addresses per object, rather than just a single name and IP address. I think you could make this considerably easier if you can change the input to be a more direct representation of the structure you are trying to produce, so that each object in the list represents only one line of the output, with only a single name and IP address each

Using the most appropriate data structure is typically the first step to making downstream use of that data structure easier. If you don’t control the input and so can’t change it, then I think you are on the right track of having a separate step to project the data structure into a more reasonable shape, and then passing the more reasonable data structure into the template.