Prerequisites (~30-60 minutes)

  1. Have an ESXi instance version 6.x. ESXi 7 is not supported. VSphere is NOT required.
  2. Install the requirements from the ESXi Terraform Provider
    • If building on MacOS, don’t forget to change the GOOS from linux to darwin!
      • GOOS=linux -> GOOS=darwin
  3. Build and install the terraform-provider-esxi provider
  4. Your ESXi must have at least two separate networks - one that is accessible from your current machine (VM Network) and a HostOnly network to allow the VMs to have internet access (HostOnly).
  5. OVFTool must be installed and in your PATH.
    • On MacOS, I solved this by creating a symbolic link to the ovftool included in VMWare Fusion: sudo ln -s "/Applications/VMware OVF Tool/ovftool" "/usr/local/bin/ovftool"
  6. On your ESXI, you must:
    1. Enable SSH
    2. Enable the “Guest IP Hack”
    3. Open VNC ports on the firewall
  7. Install Ansible and ensure it’s in your PATH.


  1. (5 Minutes) Edit the variables in DetectionLab/ESXi/Packer/variables.json to match your ESXi configuration. The esxi_network_with_dhcp_and_internet variable refers to any ESXi network that will be able to provide DHCP and internet access to the VM while it’s being built in Packer.

  2. (45 Minutes)

    At this point, we need the “base” OS to be built and deployed to ESXi, and we’ll accomplish this using Packer.

    From the DetectionLab/ESXi/Packer directory, run:

  • PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json windows_10_esxi.json
  • PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json windows_2016_esxi.json
  • PACKER_CACHE_DIR=../../Packer/packer_cache packer build -var-file variables.json ubuntu1804_esxi.json

These commands can be run in parallel from three separate terminal sessions.


  1. (1 Minute) Once the Packer builds finish, verify that you now see Windows10, WindowsServer2016, and Ubuntu1804 in your ESXi console Ansible
  2. (5 Minutes) Edit the variables in ESXi/ to match your local ESXi configuration or create a terraform.tfvars file (RECOMMENDED) to override them.
  3. (25 Minutes) From DetectionLab/ESXi, run terraform init && terraform apply
  4. Once Terraform has finished bringing the hosts online, change your directory to DetectionLab/ESXi/Ansible
  5. (1 Minute) Edit DetectionLab/ESXi/Ansible/inventory.yml and replace the IP Addresses with the respective IP Addresses of your ESXi VMs. These IP addresses much be reachable from your host machine!
  6. (3 Minutes) Edit DetectionLab/ESXi/resources/01-netcfg.yaml. These are the IP addresses that will be applied to the logger network interfaces. These should be be able to be found in your ESXi console or from the Terraform outputs.
  7. (3 Minutes) Before running any Ansible playbooks, I highly recommend taking snapshots of all your VMs! If anything goes wrong with provisioning, you can simply restore the snapshot and easily debug the issue.
  8. Change your directory to DetectionLab/ESXi/Ansible
  9. (30 Minutes) Run ansible-playbook -vvv detectionlab.yml
  10. If all goes well, you should see the following and your lab is complete! Ansible

If you run into any issues along the way, please open an issue on Github and I’ll do my best to find a solution.

Configuring Windows 10 with WSL as a Provisioning Host

Note: Run the following commands as a root user or with sudo

  1. In Windows 10 install WSL (version 1 or 2)
  2. Install Ubuntu 18.04 app from the Microsoft Store
  3. Update repositories and upgrade the distro: apt update && upgrade
  4. Ensure you will install the most recent Ansible version: apt-add-repository –yes –update ppa:ansible/ansible
  5. Install the following packages: apt install python python-pip ansible unzip sshpass libffi-dev libssl-dev
  6. Install PyWinRM using: pip install pywinrm
  7. Install Terraform and Packer by downloading the 64-bit Linux binaries and moving them to /usr/local/bin
  8. Install VMWare OVF tool by downloading 64-bit Linux binary from and running it with “–eulas-agreed” option
  9. Download the Linux binary for the Terraform ESXi Provider from and move it to /usr/local/bin
  10. From “DetectionLab/ESXi/ansible” directory, run: “ansible –version” and ensure that the config file used is “DetectionLab/ESXi/ansible/ansible.cfg”. If not, implement the Ansible “world-writtable directory” fix by going to running: “chmod o-w .” from “DetectionLab/ESXi/ansible” directory.

Future work required

Debugging / Troubleshooting

  • If an Ansible playbook fails, you can pick up where it left off with ansible-playbook -vvv detectionlab.yml --start-at-task="taskname"


As usual, this work is based off the heavy lifting that others have done. My primary sources for this work were:

Thank you to all of the sponsors who made this possible!