Unable to connect vSphereVM to NSX-T Segment in Terraform

Hi,

Recently while rebuilding the lab, I came across what seems to be a bug between the hashicorp/vsphere and the vmware/nsxt terraform providers.

For example, here's a snippet from code that should work, but doesn't:

 1resource "nsxt_policy_segment" "testinglinuxlab1" {
 2    display_name = "testinglinuxlab1"
 3    transport_zone_path = data.nsxt_policy_transport_zone.overlay_tz.path
 4    connectivity_path = data.nsxt_policy_tier1_gateway.T1Main.path
 5
 6    subnet {
 7        cidr = "10.183.94.1/24"
 8    }
 9}
10
11resource "vsphere_virtual_machine" "testinglinuxlab101" {
12  name             = "testing-linuxlab1-01"
13  resource_pool_id = data.vsphere_compute_cluster.AVA.resource_pool_id
14  datastore_id     = data.vsphere_datastore.ssd.id
15
16  num_cpus = 2
17  memory   = 2048 # in MB
18  guest_id = data.vsphere_virtual_machine.debian12-template.guest_id
19
20  network_interface {
21    network_id   = resource.nsxt_policy_segment.testinglinuxlab1.id
22    adapter_type = data.vsphere_virtual_machine.debian12-template.network_interface_types[0]
23  }
24
25  disk {
26    label            = "disk0"
27    size             = "50" # In GB
28    eagerly_scrub    = false
29    thin_provisioned = true
30  }
31
32  clone {
33    template_uuid = data.vsphere_virtual_machine.debian12-template.id
34
35    customize {
36      linux_options {
37        host_name = "testing-test01"
38        domain    = "ava.michellegoossens.com"
39      }
40
41      network_interface {
42        ipv4_address = "10.183.94.10"
43        ipv4_netmask = 24
44        dns_server_list = [ "192.168.74.112" ]
45      }
46
47      ipv4_gateway = "10.183.94.1"
48    }
49  }
50  lifecycle {
51    ignore_changes = [
52      clone[0].template_uuid
53    ]
54  }
55}

This is because the vSphere provider wants a dvPortgroup ID, but the NSX-T provider doesn't give that nor has an option (from what I could find) to give this.

The workaround here is to call vsphere_network instead. We can do that making terraform aware of it through data, and then linking it to the name of the NSX-T segment as per the snippet below:

 1resource "nsxt_policy_segment" "testinglinuxlab1" {
 2    display_name = "testinglinuxlab1"
 3    transport_zone_path = data.nsxt_policy_transport_zone.overlay_tz.path
 4    connectivity_path = data.nsxt_policy_tier1_gateway.T1Main.path
 5
 6    subnet {
 7        cidr = "10.183.94.1/24"
 8    }
 9}
10
11data "vsphere_network" "testinglinuxlab1" {
12  # Make terraform aware of the NSX segment that has the name of the resource listed above
13  name = resource.nsxt_policy_segment.testinglinuxlab1.display_name
14  datacenter_id = data.vsphere_datacenter.FSN.id
15}
16
17resource "vsphere_virtual_machine" "testinglinuxlab101" {
18  name             = "testing-linuxlab1-01"
19  resource_pool_id = data.vsphere_compute_cluster.AVA.resource_pool_id
20  datastore_id     = data.vsphere_datastore.ssd.id
21
22  num_cpus = 2
23  memory   = 2048 # in MB
24  guest_id = data.vsphere_virtual_machine.debian12-template.guest_id
25
26  network_interface {
27    # This is the NSX segment we created earlier, but through `vsphere_network`, we are able to get the dvPortgroup ID that the vSphere terraform provider wants.
28    network_id   = data.vsphere_network.testinglinuxlab1.id
29    adapter_type = data.vsphere_virtual_machine.debian12-template.network_interface_types[0]
30  }
31
32  disk {
33    label            = "disk0"
34    size             = "50" # In GB
35    eagerly_scrub    = false
36    thin_provisioned = true
37  }
38
39  clone {
40    template_uuid = data.vsphere_virtual_machine.debian12-template.id
41
42    customize {
43      linux_options {
44        host_name = "testing-test01"
45        domain    = "ava.michellegoossens.com"
46      }
47
48      network_interface {
49        ipv4_address = "10.183.94.10"
50        ipv4_netmask = 24
51        dns_server_list = [ "192.168.74.112" ]
52      }
53
54      ipv4_gateway = "10.183.94.1"
55    }
56  }
57  lifecycle {
58    ignore_changes = [
59      clone[0].template_uuid
60    ]
61  }
62}

The above is what solved it for me, so I can go back to terraform'ing the lab now. Thanks for reading!