josenk / terraform-provider-esxi

Terraform-provider-esxi plugin
GNU General Public License v3.0
540 stars 154 forks source link

Error: host for provisioner cannot be empty #125

Closed mlinton closed 3 years ago

mlinton commented 3 years ago

When attempting to apply an existing terraform plan, I get the message "Error: host for provisioner cannot be empty"

I am using terraform on a Macos machine, and attempting to build the DetectionLab (https://www.detectionlab.network/deployment/esxi/) environment.

It appears that the esxi_guest.logger is failing, but I'm not sure why and what the best way to fix it would be. I would think that it would work based on the logger guest configuration, but maybe I'm not understanding what the host option needs to be for the provisioner.

In variables.tf I specified the ip address of the esxi host, is this correct?

Thanks again for your help.

Here is the result of the terraform init:

❯ terraform init

Initializing the backend...

Initializing provider plugins...
- Using previously-installed josenk/esxi v1.8.0

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.

* josenk/esxi: version = "~> 1.8.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Here is the result of terraform plan:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

esxi_guest.dc: Refreshing state... [id=59]
esxi_guest.win10: Refreshing state... [id=60]
esxi_guest.logger: Refreshing state... [id=67]
esxi_guest.wef: Refreshing state... [id=58]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # esxi_guest.logger is tainted, so must be replaced
-/+ resource "esxi_guest" "logger" {
        boot_disk_size         = "35"
        boot_disk_type         = "thin"
        clone_from_vm          = "Ubuntu1804"
        disk_store             = "datastore1"
        guest_name             = "logger"
        guest_shutdown_timeout = 30
        guest_startup_timeout  = 45
        guestos                = "ubuntu-64"
      ~ id                     = "67" -> (known after apply)
      + ip_address             = (known after apply)
        memsize                = "4096"
      + notes                  = (known after apply)
        numvcpus               = "2"
      ~ ovf_properties_timer   = 0 -> (known after apply)
        power                  = "on"
        resource_pool_name     = "/"
      ~ virthwver              = "9" -> (known after apply)

        network_interfaces {
            mac_address     = "00:50:56:a3:b1:c2"
            nic_type        = "e1000"
            virtual_network = "vSwitch1"
        }
        network_interfaces {
            mac_address     = "00:50:56:a3:b1:c4"
            nic_type        = "e1000"
            virtual_network = "LAB"
        }
    }

  # esxi_guest.win10 will be updated in-place
  ~ resource "esxi_guest" "win10" {
        boot_disk_size         = "35"
        boot_disk_type         = "thin"
        clone_from_vm          = "Windows10"
        disk_store             = "datastore1"
        guest_name             = "win10"
        guest_shutdown_timeout = 30
        guest_startup_timeout  = 45
        guestos                = "windows9-64"
        id                     = "60"
        ip_address             = "10.20.40.222"
        memsize                = "2048"
        numvcpus               = "2"
        ovf_properties_timer   = 0
        power                  = "on"
        resource_pool_name     = "/"
        virthwver              = "11"

      ~ network_interfaces {
          ~ mac_address     = "00:50:56:a2:b1:c3" -> "00:50:56:a2:b1:c2"
            nic_type        = "e1000"
          ~ virtual_network = "Private LAN" -> "vSwitch1"
        }
      ~ network_interfaces {
          ~ mac_address     = "00:50:56:a2:b1:c4" -> "00:50:56:a2:b1:c3"
            nic_type        = "e1000"
          ~ virtual_network = "LAB" -> "Private LAN"
        }
      + network_interfaces {
          + mac_address     = "00:50:56:a2:b1:c4"
          + nic_type        = "e1000"
          + virtual_network = "LAB"
        }
    }

Plan: 1 to add, 1 to change, 1 to destroy.

Changes to Outputs:
  ~ logger_interfaces = [
      ~ {
          ~ mac_address     = "" -> "00:50:56:a3:b1:c2"
            nic_type        = "e1000"
            virtual_network = "vSwitch1"
        },
        {
            mac_address     = "00:50:56:a3:b1:c4"
            nic_type        = "e1000"
            virtual_network = "LAB"
        },
    ]
  + logger_ips        = (known after apply)
  ~ win10_interfaces  = [
      + {
          + mac_address     = "00:50:56:a2:b1:c2"
          + nic_type        = "e1000"
          + virtual_network = "vSwitch1"
        },
        {
            mac_address     = "00:50:56:a2:b1:c3"
            nic_type        = "e1000"
            virtual_network = "Private LAN"
        },
        {
            mac_address     = "00:50:56:a2:b1:c4"
            nic_type        = "e1000"
            virtual_network = "LAB"
        },
    ]

------------------------------------------------------------------------

Here is what happens when I try to apply it:

.....
esxi_guest.logger: Still creating... [15m20s elapsed]
esxi_guest.logger: Still creating... [15m30s elapsed]
esxi_guest.logger: Still creating... [15m40s elapsed]
esxi_guest.logger: Still creating... [15m50s elapsed]
esxi_guest.logger: Still creating... [16m0s elapsed]
esxi_guest.logger: Still creating... [16m10s elapsed]
esxi_guest.logger: Still creating... [16m20s elapsed]
esxi_guest.logger: Still creating... [16m30s elapsed]
esxi_guest.logger: Still creating... [16m40s elapsed]
esxi_guest.logger: Still creating... [16m50s elapsed]
esxi_guest.logger: Still creating... [17m0s elapsed]
esxi_guest.logger: Still creating... [17m10s elapsed]
esxi_guest.logger: Still creating... [17m20s elapsed]
esxi_guest.logger: Still creating... [17m30s elapsed]
esxi_guest.logger: Still creating... [17m40s elapsed]
esxi_guest.logger: Provisioning with 'remote-exec'...

Error: host for provisioner cannot be empty

Here is the contents of main.tf

#########################################
#  ESXI Provider host/login details
#########################################
#
#   Use of variables here to hide/move the variables to a separate file
#
terraform {
  required_version = ">= 0.13"
}
provider "esxi" {
  esxi_hostname = var.esxi_hostname
  esxi_hostport = var.esxi_hostport
  esxi_username = var.esxi_username
  esxi_password = var.esxi_password
}

#########################################
#  ESXI Guest resource
#########################################
resource "esxi_guest" "logger" {
  guest_name = "logger"
  disk_store = "datastore1"
  guestos    = "ubuntu-64"

  boot_disk_type = "thin"
  boot_disk_size = "35"

  memsize            = "4096"
  numvcpus           = "2"
  resource_pool_name = "/"
  power              = "on"
  clone_from_vm = "Ubuntu1804"

    provisioner "remote-exec" {
    inline = [
      "sudo ifconfig eth1 up || echo 'eth1 up'",
      "sudo ifconfig eth2 up || echo 'eth2 up'",
      "sudo route add default gw 192.168.76.1 || echo 'route exists'"
    ]

    connection {
      host        = self.ip_address
      type        = "ssh"
      user        = "vagrant"
      password    = "vagrant"
    }
  }
  # This is the network that bridges your host machine with the ESXi VM
  # If this interface doesn't provide connectivity, you will have to uncomment
  # the interface below and add a virtual network that does
  network_interfaces {
    virtual_network = var.vm_network
    mac_address     = "00:50:56:a3:b1:c2"
    nic_type        = "e1000"
  }
  # This is the local network that will be used for 192.168.38.x addressing
  network_interfaces {
    virtual_network = var.hostonly_network
    mac_address     = "00:50:56:a3:b1:c4"
    nic_type        = "e1000"
  }
  # OPTIONAL: Uncomment out this interface stanza if your vm_network doesn't
  # provide internet access
  # network_interfaces {
  #  virtual_network = var.nat_network
  #  mac_address     = "00:50:56:a3:b1:c3"
  #  nic_type        = "e1000"
  # }
  guest_startup_timeout  = 45
  guest_shutdown_timeout = 30
}

resource "esxi_guest" "dc" {
  guest_name = "dc"
  disk_store = "datastore1"
  guestos    = "windows9srv-64"

  boot_disk_type = "thin"
  boot_disk_size = "35"

  memsize            = "4096"
  numvcpus           = "2"
  resource_pool_name = "/"
  power              = "on"
  clone_from_vm = "WindowsServer2016"
  # This is the network that bridges your host machine with the ESXi VM
  network_interfaces {
    virtual_network = var.vm_network
    mac_address     = "00:50:56:a1:b1:c2"
    nic_type        = "e1000"
  }
  # OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
  network_interfaces {
    virtual_network = var.nat_network
    mac_address     = "00:50:56:a1:b1:c3"
    nic_type        = "e1000"
  }
  # This is the local network that will be used for 192.168.38.x addressing
  network_interfaces {
    virtual_network = var.hostonly_network
    mac_address     = "00:50:56:a1:b1:c4"
    nic_type        = "e1000"
  }
  guest_startup_timeout  = 45
  guest_shutdown_timeout = 30
}

resource "esxi_guest" "wef" {
  guest_name = "wef"
  disk_store = "datastore1"
  guestos    = "windows9srv-64"

  boot_disk_type = "thin"
  boot_disk_size = "35"

  memsize            = "2048"
  numvcpus           = "2"
  resource_pool_name = "/"
  power              = "on"
  clone_from_vm = "WindowsServer2016"
  # This is the network that bridges your host machine with the ESXi VM
  network_interfaces {
    virtual_network = var.vm_network
    mac_address     = "00:50:56:a1:b2:c2"
    nic_type        = "e1000"
  }
  # OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
  network_interfaces {
    virtual_network = var.nat_network
    mac_address     = "00:50:56:a1:b3:c3"
    nic_type        = "e1000"
  }
  # This is the local network that will be used for 192.168.38.x addressing
  network_interfaces {
    virtual_network = var.hostonly_network
    mac_address     = "00:50:56:a1:b4:c4"
    nic_type        = "e1000"
  }
  guest_startup_timeout  = 45
  guest_shutdown_timeout = 30
}

resource "esxi_guest" "win10" {
  guest_name = "win10"
  disk_store = "datastore1"
  guestos    = "windows9-64"

  boot_disk_type = "thin"
  boot_disk_size = "35"

  memsize            = "2048"
  numvcpus           = "2"
  resource_pool_name = "/"
  power              = "on"
  clone_from_vm = "Windows10"
  # This is the network that bridges your host machine with the ESXi VM
  network_interfaces {
    virtual_network = var.vm_network
    mac_address     = "00:50:56:a2:b1:c2"
    nic_type        = "e1000"
  }
  # OPTIONAL: You can comment out this interface stanza if your vm_network provides internet access
  network_interfaces {
    virtual_network = var.nat_network
    mac_address     = "00:50:56:a2:b1:c3"
    nic_type        = "e1000"
  }
  # This is the local network that will be used for 192.168.38.x addressing
  network_interfaces {
    virtual_network = var.hostonly_network
    mac_address     = "00:50:56:a2:b1:c4"
    nic_type        = "e1000"
  }
  guest_startup_timeout  = 45
  guest_shutdown_timeout = 30
}

Here is the contents of variables.tf

❯ more variables.tf
#
#  See https://www.terraform.io/intro/getting-started/variables.html for more details.
#
#  Change these defaults to fit your needs!

variable "esxi_hostname" {
  default = "10.20.40.2"
}

variable "esxi_hostport" {
  default = "22"
}

variable "esxi_username" {
  default = "root"
}

variable "esxi_password" { # Unspecified will prompt
}

variable "vm_network" {
  default = "vSwitch1"
}

variable "nat_network" {
  default = "Private LAN"
}

variable "hostonly_network" {
  default = "LAB"
}

Expected behavior A clear and concise description of what you expected to happen.

Terraform files Provide a minimalist main.tf and other terraform files that reproduces your issue. If your problem is related to terraform plan/apply/etc, most likely these files will be REQUIRED.

Desktop (please complete the following information):

Additional context

josenk commented 3 years ago

Sorry, I don't support detectionlab, or any provisioners. The error you see is concerning the 'host' line of the remote-exec provioner. It looks like you are setting network parameters and gateway there... Take a look at some closed issues and the wiki concerning networking...

mlinton commented 3 years ago

Ok thanks!