String required variable interpolation tor template

Hello,

I’m having an issue when trying to work with a cloud-init template on terraform. This is what the template looks like:

  1 local-hostname: ${name}
  2 network:
  3   version: 2
  4   ethernets:
  5     ens192:
  6 %{ if private_ip != "" ~}
  7       addresses: ["${private_ip}/24"]
  8       gateway4: ${private_gateway}
  9 %{ else ~}
 10       dhcp4: true
 11       dhcp-identifier: mac
 12 %{ endif ~}
 13 %{ if length(routes) > 0 ~}
 14       routes:
 15 %{ for route in routes ~}
 16         - to: ${route["to"]}
 17           via: ${route["via"]}
 18 %{ if private_ip == "" ~}
 19           on-link: true
 20 %{ endif ~}
 21 %{ endfor ~}
 22 %{ endif ~}
 23 %{ if public_ip != "" ~}
 24     ens224:
 25       addresses: ["${public_ip}/24"]
 26       gateway4: ${public_gateway}
 27 %{ endif ~}

The error is the following:

  1 local-hostname: ${name}
│ Error: Error in function call
│
│   on main.tf line 156, in resource "vsphere_virtual_machine" "consul_vm":
│  156:     "guestinfo.metadata" = base64gzip(templatefile("${path.module}/files/common/metadata.tpl", {
│  157:       name       = "${each.value}"
│  158:       private_ip = "${each.value["ip_address"]}", private_gateway = "10.88.88.126"
│  159:       public_ip  = "", public_gateway = ""
│  160:       routes     = []
│  161:     }))
│     ├────────────────
│     │ each.value is object with 1 attribute "ip_address"
│     │ each.value["ip_address"] is "10.88.88.216"
│     │ path.module is "."
│
│ Call to function "templatefile" failed: ./files/common/metadata.tpl:1,19-23: Invalid
│ template interpolation value; Cannot include the given value in a string template:
│ string required..
╵

And this is what the guestinfo.metadata looks like:

    "guestinfo.metadata" = base64gzip(templatefile("${path.module}/files/common/metadata.tpl", {
      name       = "${each.value}"
      private_ip = "${each.value["ip_address"]}", private_gateway = "10.88.88.126"
      public_ip  = "", public_gateway = ""
      routes     = []
    }))
  }

So the problem seems to be related to lines 19-23, but I cannot figure out what’s wrong with them.
I tried to apply tostring, just for the sake of it, but to no avail. I’m not sure what I’m doing wrong.

Hi @lethargosapatheia,

The error message says that each.value is an object, so it seems correct that it isn’t allowed to interpolate this value.

I’m not sure what to suggest instead though since I don’t know what you intend to use as the value for “local-hostname” in your YAML.

If you can show an example of what you expect the final result of this template to be then I can hopefully show you at least one way to achieve that result.

1 Like

So you mean to say that the error isn’t referring to the each.value["ip_address"], but the each_value? And I’m guessing this is something you’ve inferred from what you’ve seen, but not from the referenced lines.

This what the variable looks like:

consul_servers = {
	consul-0 = {
		ip_address = "10.88.88.215"
	}

	consul-1 = {
		ip_address = "10.88.88.216"
	}

	consul-2 = {
		ip_address = "10.88.88.217"
	}
}

Ok, I think I know where the confusing comes from, I was wondering why I didn’t have this issue with proxmox. I was simply mixing up key with value.

Thanks! This has helped me to look in the right direction. It works now!