Deploying ESXi from OVF completes without network adaptor

Hey Terraform Community, I’m new to Terraform and having an issue that I’m not sure how to resolve/troubleshoot. I’m deploying an ESXi host from OVF and for unknown reason it deploys without a network card. If I edit the VM after power on and add a NIC it successfully applies the IP information I provided in the main.tf. I can post more info about my config but thought maybe I could get some suggestions on how to troubleshoot this further.

This config was edited to fit my lab. It was originally William Lam’s config so I’m pretty sure it worked for him.

Another thing to note is that it’s not taking any of the OVF properties. If you don’t specify cpu/mem it powers on with the defaults which is too small for ESXi and it purple screens on boot.

I’ve tried this with

  • different terraform installs
  • against VC 6.7 and 7.0
  • with different OVF files

terraform {
required_providers {
vsphere = {
source = “hashicorp/vsphere”
version = “1.25.0”
}
}
}
provider “vsphere” {
user = “administrator@stevelab.local”
password = “VMware1!steve”
vsphere_server = “stevelab-dell-infra-vc.stevelab.local”

If you have a self-signed cert

allow_unverified_ssl = true
}
data “vsphere_datacenter” “datacenter” {
name = “dell-infra-dc”
}
#data “vsphere_compute_cluster” “cluster” {

name = “Dell-Infra-Cluster”

datacenter_id = data.vsphere_datacenter.datacenter.id

#}
data “vsphere_datastore” “datastore” {
name = “stevelab-nfs-pod3”
datacenter_id = data.vsphere_datacenter.datacenter.id
}
data “vsphere_resource_pool” “pool” {
name = “Terraform-Landing”
datacenter_id = data.vsphere_datacenter.datacenter.id
}
data “vsphere_network” “network” {
name = “Pod3-VLAN-30”
datacenter_id = data.vsphere_datacenter.datacenter.id
}
data “vsphere_host” “host” {
name = “stevelab-dell-esx3.stevelab.local”
datacenter_id = data.vsphere_datacenter.datacenter.id
}
resource “vsphere_virtual_machine” “vmFromLocalOvf” {
name = “stevelab-3-vesxi7”
resource_pool_id = data.vsphere_resource_pool.pool.id
datastore_id = data.vsphere_datastore.datastore.id
datacenter_id = data.vsphere_datacenter.datacenter.id
host_system_id = data.vsphere_host.host.id
num_cpus = 4
memory = 32768
guest_id = “vmkernel65Guest”
nested_hv_enabled =true
wait_for_guest_net_timeout = 0
wait_for_guest_ip_timeout = 0
ovf_deploy {
local_ovf_path = “/Users/steve/Downloads/Nested_ESXi7.0u1_Appliance_Template_v1.ova”
disk_provisioning = “thin”
ip_protocol = “IPV4”
ip_allocation_policy = “STATIC_MANUAL”
ovf_network_map = {
“POD3-VLAN-30” = data.vsphere_network.network.id
}
}
vapp {
properties = {
“guestinfo.hostname” = “stevelab-3-vesxi7”,
“guestinfo.ipaddress” = “192.168.30.45”,
“guestinfo.netmask” = “255.255.255.0”,
“guestinfo.gateway” = “192.168.30.1”,
“guestinfo.dns” = “192.168.30.1”,
“guestinfo.domain” = “stevelab.local”,
“guestinfo.ntp” = “pool.ntp.org”,
“guestinfo.password” = “VMware1!23”,
“guestinfo.ssh” = “True”
}
}
}

Hopefully I can get someone to help me troubleshoot.

I think target of output of terraform command is very usefule. At first you have write output.tf. for more information: Command: output | Terraform by HashiCorp

Here’s an example that will deploy two of Williams’s nested ESXi 7.0.3 OVFs, one from a local instance of the OVA and one from the URL.

Ensure that you are using the latest version of the provider, v2.0.2 as of this date.

provider "vsphere" {
  vsphere_server       = var.vsphere_server
  user                 = var.vsphere_username
  password             = var.vsphere_password
  allow_unverified_ssl = var.vsphere_insecure
}

data "vsphere_datacenter" "datacenter" {
  name = "m01-dc01"
}

data "vsphere_datastore" "datastore" {
  name          = "local-ssd-01"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_compute_cluster" "cluster" {
  name          = "m01-cl01"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_resource_pool" "default" {
  name          = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources")
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_host" "host" {
  name          = "m01-esx01.rainpole.io"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_network" "network" {
  name          = "M - 172.16.11.0"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

data "vsphere_folder" "folder" {
  path = "/${data.vsphere_datacenter.datacenter.name}/vm"
}

## Remote OVF/OVA Source
data "vsphere_ovf_vm_template" "ovfRemote" {
  name              = "foo"
  disk_provisioning = "thin"
  resource_pool_id  = data.vsphere_resource_pool.default.id
  datastore_id      = data.vsphere_datastore.datastore.id
  host_system_id    = data.vsphere_host.host.id
  remote_ovf_url    = "https://download3.vmware.com/software/vmw-tools/nested-esxi/Nested_ESXi7.0u3_Appliance_Template_v1.ova"
  ovf_network_map = {
    "VM Network" : data.vsphere_network.network.id
  }
}

## Local OVF/OVA Source
data "vsphere_ovf_vm_template" "ovfLocal" {
  name              = "foo"
  disk_provisioning = "thin"
  resource_pool_id  = data.vsphere_resource_pool.default.id
  datastore_id      = data.vsphere_datastore.datastore.id
  host_system_id    = data.vsphere_host.host.id
  local_ovf_path    = "/Users/johnsonryan/Downloads/Nested_ESXi7.0u3_Appliance_Template_v1.ova"
  ovf_network_map = {
    "VM Network" : data.vsphere_network.network.id
  }
}

## Deployment of VM from Remote OVF
resource "vsphere_virtual_machine" "vmFromRemoteOvf" {
  name                 = "Nested-ESXi-7.0-Terraform-Deploy-1"
  folder               = trimprefix(data.vsphere_folder.folder.path, "/${data.vsphere_datacenter.datacenter.name}/vm")
  datacenter_id        = data.vsphere_datacenter.datacenter.id
  datastore_id         = data.vsphere_datastore.datastore.id
  host_system_id       = data.vsphere_host.host.id
  resource_pool_id     = data.vsphere_resource_pool.default.id
  num_cpus             = data.vsphere_ovf_vm_template.ovfRemote.num_cpus
  num_cores_per_socket = data.vsphere_ovf_vm_template.ovfRemote.num_cores_per_socket
  memory               = data.vsphere_ovf_vm_template.ovfRemote.memory
  guest_id             = data.vsphere_ovf_vm_template.ovfRemote.guest_id
  scsi_type            = data.vsphere_ovf_vm_template.ovfRemote.scsi_type
  nested_hv_enabled    = data.vsphere_ovf_vm_template.ovfRemote.nested_hv_enabled
  dynamic "network_interface" {
    for_each = data.vsphere_ovf_vm_template.ovfRemote.ovf_network_map
    content {
      network_id = network_interface.value
    }
  }
  wait_for_guest_net_timeout = 0
  wait_for_guest_ip_timeout  = 0

  ovf_deploy {
    allow_unverified_ssl_cert = false
    remote_ovf_url            = data.vsphere_ovf_vm_template.ovfRemote.remote_ovf_url
    disk_provisioning         = data.vsphere_ovf_vm_template.ovfRemote.disk_provisioning
    ovf_network_map           = data.vsphere_ovf_vm_template.ovfRemote.ovf_network_map
  }

  vapp {
    properties = {
      "guestinfo.hostname"  = "nested-esxi-01.example.com",
      "guestinfo.ipaddress" = "172.16.11.101",
      "guestinfo.netmask"   = "255.255.255.0",
      "guestinfo.gateway"   = "172.16.11.1",
      "guestinfo.dns"       = "172.16.11.4",
      "guestinfo.domain"    = "example.com",
      "guestinfo.ntp"       = "ntp.example.com",
      "guestinfo.password"  = "VMware1!",
      "guestinfo.ssh"       = "True"
    }
  }

  lifecycle {
    ignore_changes = [
      annotation,
      disk[0].io_share_count,
      disk[1].io_share_count,
      disk[2].io_share_count,
      vapp[0].properties,
    ]
  }
}

## Deployment of VM from Local OVF
resource "vsphere_virtual_machine" "vmFromLocalOvf" {
  name                 = "Nested-ESXi-7.0-Terraform-Deploy-2"
  folder               = trimprefix(data.vsphere_folder.folder.path, "/${data.vsphere_datacenter.datacenter.name}/vm")
  datacenter_id        = data.vsphere_datacenter.datacenter.id
  datastore_id         = data.vsphere_datastore.datastore.id
  host_system_id       = data.vsphere_host.host.id
  resource_pool_id     = data.vsphere_resource_pool.default.id
  num_cpus             = data.vsphere_ovf_vm_template.ovfLocal.num_cpus
  num_cores_per_socket = data.vsphere_ovf_vm_template.ovfLocal.num_cores_per_socket
  memory               = data.vsphere_ovf_vm_template.ovfLocal.memory
  guest_id             = data.vsphere_ovf_vm_template.ovfLocal.guest_id
  scsi_type            = data.vsphere_ovf_vm_template.ovfLocal.scsi_type
  nested_hv_enabled    = data.vsphere_ovf_vm_template.ovfLocal.nested_hv_enabled
  dynamic "network_interface" {
    for_each = data.vsphere_ovf_vm_template.ovfLocal.ovf_network_map
    content {
      network_id = network_interface.value
    }
  }
  wait_for_guest_net_timeout = 0
  wait_for_guest_ip_timeout  = 0

  ovf_deploy {
    allow_unverified_ssl_cert = false
    local_ovf_path            = data.vsphere_ovf_vm_template.ovfLocal.local_ovf_path
    disk_provisioning         = data.vsphere_ovf_vm_template.ovfLocal.disk_provisioning
    ovf_network_map           = data.vsphere_ovf_vm_template.ovfLocal.ovf_network_map
  }

  vapp {
    properties = {
      "guestinfo.hostname"  = "nested-esxi-02.example.com",
      "guestinfo.ipaddress" = "172.16.11.102",
      "guestinfo.netmask"   = "255.255.255.0",
      "guestinfo.gateway"   = "172.16.11.1",
      "guestinfo.dns"       = "172.16.11.4",
      "guestinfo.domain"    = "example.com",
      "guestinfo.ntp"       = "ntp.example.com",
      "guestinfo.password"  = "VMware1!",
      "guestinfo.ssh"       = "True"
    }
  }

  lifecycle {
    ignore_changes = [
      annotation,
      disk[0].io_share_count,
      disk[1].io_share_count,
      disk[2].io_share_count,
      vapp[0].properties,
    ]
  }
}

Ryan

You can use of modify the folder data source and attributes if they cause you trouble. It’s just how I do it.