Can't extract ipv4 value - errors

Hello, any idea how to extract from the code below fixed_ip_v4 for network named test? I’d like to extract that value for ansible inventory.

resource "openstack_compute_instance_v2" "test_terraform_instance" {
  name        = "tmpnode${count.index}"
  count       = var.node_count
  provider    = openstack.ovh
  image_name  = "Debian 10"
  flavor_name = var.flavor_name  #"s1-2"
  key_pair    = openstack_compute_keypair_v2.test_keypair.name
  network {
    name      = "Ext-Net"
  }
  network {
    name = "test"
    fixed_ip_v4 = element(var.front_private_ip, count.index)
  }
}

What I already tried and the errors:

  • openstack_compute_instance_v2.test_terraform_instance[*].network.name[test].fixed_ip_v4 ?

    Can’t access attributes on a list of objects. Did you mean to access attribute “name” for a specific element of the list, or across all elements of the list?

  • openstack_compute_instance_v2.test_terraform_instance[*].network[*].fixed_ip_v4.network[“test”].fixed_ip_v4


    Doesn’t work without double and with single quotes in network[“test”] neither.

@gc-ss

1 Like

Hi @maarsaks!

I’m not really familiar with the OpenStack provider, but the error message seems to be explaining that the fixed_ip_v4 attribute is just a string, and so it doesn’t make sense to access any attributes on it.

Because the network name is in a separate attribute alongside fixed_ip_v4, rather than being a map key, I think the only way to select by name would be to first project this data structure into a more useful shape where you can look up the networks by their names:

locals {
  instance_networks = [
    for inst in openstack_compute_instance_v2.test_terraform_instance : {
      for net in inst.network : net.name => net
    }
  ]
}

The above uses nested for expressions to produce a simplified data structure that just captures the networks for each of the instances, each one identified by its name value. So local.instance_networks should therefore have a structure something like this:

[
  {
    "Ext-Net" = {
      name = "Ext-Net"
    }
    "test" = {
      name        = "test"
      fixed_ip_v4 = "10.1.0.1"
    }
  },
  {
    "Ext-Net" = {
      name = "Ext-Net"
    }
    "test" = {
      name        = "test"
      fixed_ip_v4 = "10.1.0.2"
    }
  },
]

This is a list of maps of objects, which is a more convenient shape to use with the splat operator:

  ip = local.instance_networks[*].test.fixed_ip_v4

In other words, take each element of the sequence in local.instance_networks, access the test key from each map, and then from there access the fixed_ip_v4 attribute of the resulting object.

2 Likes