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!