***Terraform Deck front slide

Recently my colleague and friend, James and I had the opportunity to present at VMware Explore Las Vegas & Barcelona 2024 on VCF and the VCF Terraform provider and how it can simplify the bring up operation and other important post bring up activities.

Over the course of the next few blog post I will dive into each topic we covered during the session and explain the code in more depth.

We will begin with the initial bring up operation of VCF using the VCF Provider.

Tip: This assumes you have all the prerequisites in place such as built ESXi hosts, DNS configured and Cloud Builder deployed. You could of course make use of other Terraform providers for this such as the vSphere Provider if this is a nested test environment to deploy the hosts and Cloud Builder appliance.

Let begin by taking a look at the 4 files we are going to be using in this Terraform configuration.

provider.tf     Contains the configuration related to the required providers we are consuming.
variables.tf    Configuration for all variables we are declaring and consuming in our configuration.
main.tf         The file where the main configuration is defined.
vars.tfvars     The values for each variable we are consuming.

Provider.tf

Now lets explore the providers.tf file and see what we have.

## Terraform Providers
terraform {
  required_providers {
    vcf = {
      source  = "vmware/vcf"
      version = "0.9.1"
    }
  }
}

#Provider Configuration Options
provider "vcf" {
  cloud_builder_host     = var.cloud_builder_host
  cloud_builder_username = var.cloud_builder_username
  cloud_builder_password = var.cloud_builder_password
  allow_unverified_tls   = true
}

The first block defines the providers that we need is required, vmware/vcf and the version of that provider, in this case version 0.9.1. The second block defines the configuration options needed to use the provider:

These options are set using variables (var.), which are defined in our variables.tf file that we will take a look at next…

Variables.tf

Next lets look at our variables.tf file. This is where we are declaring the name of a variable that we wish to consume, like we did in the providers.tf file, ‘var.cloud_builder_host’ for instance.

# Variables

# Password variables
variable "cloud_builder_password" {
  description = "CloudBuilder Password"
  sensitive   = true
  type        = string
}
variable "sddc_manager_root_user_password" {
  description = "SDDC Manager root Password"
  sensitive   = true
  type        = string

}
variable "sddc_manager_secondary_user_password" {
  description = "SDDC Manager VCF User Password"
  sensitive   = true
  type        = string

}
variable "nsx_admin_password" {
  description = "NSX Admin Password"
  sensitive   = true
  type        = string

}
variable "nsx_audit_password" {
  type        = string
  description = "NSX Audit Password"
  sensitive   = true
}
variable "root_nsx_manager_password" {
  description = "NSX Manager Root Password"
  sensitive   = true
  type        = string
}
variable "admin_user_sso_password" {
  description = "PSC SSO Password"
  sensitive   = true
  type        = string

}
variable "root_vcenter_password" {
  description = "SDDC Manager Root Password"
  sensitive   = true
  type        = string
}
variable "esx_host1_password" {
  description = "ESXi Host 01 Root Password"
  sensitive   = true
  type        = string
}
variable "esx_host2_password" {
  description = "ESXi Host 01 Root Password"
  sensitive   = true
  type        = string
}
variable "esx_host3_password" {
  description = "ESXi Host 01 Root Password"
  sensitive   = true
  type        = string
}
variable "esx_host4_password" {
  description = "ESXi Host 01 Root Password"
  sensitive   = true
  type        = string
}

# Provider variables
variable "cloud_builder_username" {
  description = "CloudBuilder Username"
  default     = "admin"
  sensitive   = true
  type        = string
}
variable "cloud_builder_host" {
  description = "CloudBuilder FQDN"
  type        = string
}

# SDDC Manager variables
# Note: Each variable has been declared as its own variable with a type.
variable "vcf_instance_demo_instance_id" {
  description = "SDDC Manager Instance ID Name"
  type        = string
}
variable "vcf_instance_demo_dv_switch_version" {
  description = "Distributed Switch Version"
  type        = string
}
variable "vcf_instance_demo_skip_esx_thumbprint_validation" {
  description = "Option to skip SSL validation"
  type        = bool
}
variable "vcf_instance_demo_management_pool_name" {
  description = "Management IP Pool Name"
  type        = string
}
variable "vcf_instance_demo_ceip_enabled" {
  description = "Enable CEIP true or False"
  type        = bool
}
variable "vcf_instance_demo_task_name" {
  description = "Task path and file name"
  type        = string
}
variable "vcf_instance_demo_sddc_manager_ip_address" {
  description = "IP Address for the SDDC Manager "
  type        = string
}
variable "vcf_instance_demo_sddc_manager_hostname" {
  description = "Hostname for the SDDC Manager "
  type        = string
}
variable "vcf_instance_demo_sddc_manager_root_user_username" {
  description = "SDDC Manager root username"
  default     = "root"
  type        = string
}
variable "vcf_instance_demo_sddc_manager_secondary_user_username" {
  description = "SDDC Manager vcf username"
  default     = "vcf"
  type        = string
}

# NTP variables
variable "vcf_instance_demo_ntp" {
  description = "NTP Server (currently single entry, change to block for multiple)"
  type        = string
}

# DNS variables
variable "vcf_instance_demo_dns_domain" {
  description = "DNS domain name"
  type        = string
}
variable "vcf_instance_demo_dns_name_server" {
  description = "DNS server IP"
  type        = string
}

# Management network variables
variable "vcf_instance_demo_network_management" {
  description = "Management network configuration details"
  type = object({
    subnet       = string
    vlan_id      = number
    mtu          = number
    network_type = string
    gateway      = string
  })
}

# VM Management network variables
# Note: A single variables has been declared but contains multiple attributes, each with a type per attribute.

variable "vcf_instance_demo_network_vm_management" {
  description = "VM management network configuration details"
  type = object({
    subnet         = string
    vlan_id        = number
    mtu            = number
    network_type   = string
    gateway        = string
    port_group_key = string
  })
}

# vMotion network variables
variable "vcf_instance_demo_network_vmotion" {
  description = "vMotion network configuration details"
  type = object({
    subnet       = string
    vlan_id      = number
    mtu          = number
    network_type = string
    gateway      = string
    include_ip_address_ranges = object({
      ip_address_ranges_start = string
      ip_address_ranges_end   = string
    })
  })
}

# vSAN network variables
variable "vcf_instance_demo_network_vsan" {
  description = "vSAN network configuration details"
  type = object({
    subnet       = string
    vlan_id      = number
    mtu          = number
    network_type = string
    gateway      = string
    include_ip_address_ranges = object({
      ip_address_ranges_start = string
      ip_address_ranges_end   = string
    })

  })
}

# NSX variables
variable "vcf_instance_demo_nsx" {
  description = "NSX deployment configuration details"
  type = object({
    nsx_manager_size  = string
    vip               = string
    vip_fqdn          = string
    transport_vlan_id = number
    nsx_manager_a = object({
      hostname = string
      ip       = string
    })
    nsx_manager_b = object({
      hostname = string
      ip       = string
    })
    nsx_manager_c = object({
      hostname = string
      ip       = string
    })
    ip_address_pool = object({
      name = string #No spaces!!
      subnet = object({
        cidr    = string
        gateway = string
        ip_address_pool_range = object({
          start = string
          end   = string
        })
      })
    })
    overlay_transport_zone = object({
      zone_name    = string
      network_name = string
    })
  })
}
#vDS configurations
variable "vcf_instance_demo_vds" {
  description = "vDS configuration details"
  type = object({

    dvs_name = string
    mtu      = number
    nioc_vsan = object({
      traffic_type = string
      value        = string
    })
    nioc_vmotion = object({
      traffic_type = string
      value        = string
    })
    nioc_vm = object({
      traffic_type = string
      value        = string
    })
    nioc_management = object({
      traffic_type = string
      value        = string
    })
    nioc_vdp = object({
      traffic_type = string
      value        = string
    })
    nioc_nfs = object({
      traffic_type = string
      value        = string
    })
    nioc_hbr = object({
      traffic_type = string
      value        = string
    })
    nioc_fault = object({
      traffic_type = string
      value        = string
    })
    nioc_iscsi = object({
      traffic_type = string
      value        = string
    })
    vmnics   = list(string)
    networks = list(string)
  })
}
# Cluster configuration
variable "vcf_instance_demo_cluster" {
  description = "Cluster configuration details"
  type = object({
    cluster_name = string
    resource_pool_management = object({
      name         = string
      network_type = string
    })
    resource_pool_network = object({
      name         = string
      network_type = string
    })
  })
}
# PSC variables
variable "vcf_instance_demo_psc" {
  description = "PSC configuration details"
  type = object({
    psc_sso_domain = string
  })
}
# vCenter variables
variable "vcf_instance_demo_vCenter" {
  description = "vCenter configuration details"
  type = object({
    vcenter_ip       = string
    vcenter_hostname = string
    vm_size          = string
  })
}

# vSAN variables
variable "vcf_instance_demo_vSAN" {
  description = "vSAN configuration details"
  type = object({
    datastore_name = string
  })
}

#ESXi variables
variable "vcf_instance_demo_esx_host1" {
  description = "ESXi Host 1 configuration details"
  type = object({
    credentials = object({
      username = string
    })
    ip_address_private = object({
      subnet     = string
      ip_address = string
      gateway    = string
    })
    hostname    = string
    vswitch     = string
    association = string
  })
}
variable "vcf_instance_demo_esx_host2" {
  description = "ESXi Host 2 configuration details"
  type = object({
    credentials = object({
      username = string
    })
    ip_address_private = object({
      subnet     = string
      ip_address = string
      gateway    = string
    })
    hostname    = string
    vswitch     = string
    association = string
  })
}
variable "vcf_instance_demo_esx_host3" {
  description = "ESXi Host 3 configuration details"
  type = object({
    credentials = object({
      username = string
    })
    ip_address_private = object({
      subnet     = string
      ip_address = string
      gateway    = string
    })
    hostname    = string
    vswitch     = string
    association = string
  })
}
variable "vcf_instance_demo_esx_host4" {
  description = "ESXi Host 4 configuration details"
  type = object({
    credentials = object({
      username = string
    })
    ip_address_private = object({
      subnet     = string
      ip_address = string
      gateway    = string
    })
    hostname    = string
    vswitch     = string
    association = string
  })
}

#License variables
variable "vcf_instance_demo_license_key" {
  description = "License values"
  sensitive   = true
  type = object({
    nsx     = string
    vcenter = string
    vsan    = string
    esxi    = string
  })
}

There a many different ways to define a variable, as a single variable with a single value or and object that can contain many key value pairs. We can also define a description, flag the variable as sensitive, set a default value and also define the variable type such as string, number, boolean etc. There are other parameters for a variable such as validate, we will see examples of this in later blog posts.

Text, text, text… Codeium?

Main.tf

Moving onto the main.tf file now, this is where we are going to define the actual resources we want to deploy.

# VCF Instance Bringup
resource "vcf_instance" "demo" {
  instance_id                    = var.vcf_instance_demo_instance_id
  dv_switch_version              = var.vcf_instance_demo_dv_switch_version
  skip_esx_thumbprint_validation = var.vcf_instance_demo_skip_esx_thumbprint_validation
  management_pool_name           = var.vcf_instance_demo_management_pool_name
  ceip_enabled                   = var.vcf_instance_demo_ceip_enabled
  esx_license                    = var.vcf_instance_demo_license_key.esxi
  task_name                      = var.vcf_instance_demo_task_name
  sddc_manager {
    ip_address = var.vcf_instance_demo_sddc_manager_ip_address
    hostname   = var.vcf_instance_demo_sddc_manager_hostname
    root_user_credentials {
      username = var.vcf_instance_demo_sddc_manager_root_user_username
      password = var.sddc_manager_root_user_password
    }
    second_user_credentials {
      username = var.vcf_instance_demo_sddc_manager_secondary_user_username
      password = var.sddc_manager_secondary_user_password
    }
  }
  # NTP and DNS Configuration
  ntp_servers = [
    var.vcf_instance_demo_ntp
  ]
  dns {
    domain      = var.vcf_instance_demo_dns_domain
    name_server = var.vcf_instance_demo_dns_name_server
  }
  # Manangement Subnet Configuration
  network {
    subnet       = var.vcf_instance_demo_network_management.subnet
    vlan_id      = var.vcf_instance_demo_network_management.vlan_id
    mtu          = var.vcf_instance_demo_network_management.mtu
    network_type = var.vcf_instance_demo_network_management.network_type
    gateway      = var.vcf_instance_demo_network_management.gateway
  }
  # VM Managment Subnet Configuration
  network {
    subnet         = var.vcf_instance_demo_network_vm_management.subnet
    vlan_id        = var.vcf_instance_demo_network_vm_management.vlan_id
    mtu            = var.vcf_instance_demo_network_vm_management.mtu
    network_type   = var.vcf_instance_demo_network_vm_management.network_type
    gateway        = var.vcf_instance_demo_network_vm_management.gateway
    port_group_key = var.vcf_instance_demo_network_vm_management.port_group_key #Extra parameter needed as it is not a default subnet deployment.
  }
  # vMotion Subnet Configuration
  network {
    subnet       = var.vcf_instance_demo_network_vmotion.subnet
    vlan_id      = var.vcf_instance_demo_network_vmotion.vlan_id
    mtu          = var.vcf_instance_demo_network_vmotion.mtu
    network_type = var.vcf_instance_demo_network_vmotion.network_type
    gateway      = var.vcf_instance_demo_network_vmotion.gateway
    include_ip_address_ranges {
      start_ip_address = var.vcf_instance_demo_network_vmotion.include_ip_address_ranges.ip_address_ranges_start
      end_ip_address   = var.vcf_instance_demo_network_vmotion.include_ip_address_ranges.ip_address_ranges_end
    }
  }
  # vSAN Subnet Configuration
  network {
    subnet       = var.vcf_instance_demo_network_vsan.subnet
    vlan_id      = var.vcf_instance_demo_network_vsan.vlan_id
    mtu          = var.vcf_instance_demo_network_vsan.mtu
    network_type = var.vcf_instance_demo_network_vsan.network_type
    gateway      = var.vcf_instance_demo_network_vsan.gateway
    include_ip_address_ranges {
      start_ip_address = var.vcf_instance_demo_network_vsan.include_ip_address_ranges.ip_address_ranges_start
      end_ip_address   = var.vcf_instance_demo_network_vsan.include_ip_address_ranges.ip_address_ranges_end
    }
  }
  # NSX Configuration
  nsx {
    nsx_manager_size          = var.vcf_instance_demo_nsx.nsx_manager_size
    vip                       = var.vcf_instance_demo_nsx.vip
    vip_fqdn                  = var.vcf_instance_demo_nsx.vip_fqdn
    license                   = var.vcf_instance_demo_license_key.nsx
    transport_vlan_id         = var.vcf_instance_demo_nsx.transport_vlan_id
    root_nsx_manager_password = var.root_nsx_manager_password
    nsx_admin_password        = var.nsx_admin_password
    nsx_audit_password        = var.nsx_audit_password
    nsx_manager {
      hostname = var.vcf_instance_demo_nsx.nsx_manager_a.hostname
      ip       = var.vcf_instance_demo_nsx.nsx_manager_a.ip
    }
    nsx_manager {
      hostname = var.vcf_instance_demo_nsx.nsx_manager_b.hostname
      ip       = var.vcf_instance_demo_nsx.nsx_manager_b.ip
    }
    nsx_manager {
      hostname = var.vcf_instance_demo_nsx.nsx_manager_c.hostname
      ip       = var.vcf_instance_demo_nsx.nsx_manager_c.ip
    }
    ip_address_pool {
      name = var.vcf_instance_demo_nsx.ip_address_pool.name
      subnet {
        cidr    = var.vcf_instance_demo_nsx.ip_address_pool.subnet.cidr
        gateway = var.vcf_instance_demo_nsx.ip_address_pool.subnet.gateway
        ip_address_pool_range {
          start = var.vcf_instance_demo_nsx.ip_address_pool.subnet.ip_address_pool_range.start
          end   = var.vcf_instance_demo_nsx.ip_address_pool.subnet.ip_address_pool_range.end
        }
      }
    }
    overlay_transport_zone {
      zone_name    = var.vcf_instance_demo_nsx.overlay_transport_zone.zone_name
      network_name = var.vcf_instance_demo_nsx.overlay_transport_zone.network_name
    }
  }
  dvs {
    dvs_name = var.vcf_instance_demo_vds.dvs_name
    mtu      = var.vcf_instance_demo_vds.mtu
    # Network I/O Control Configuration. Configure all Traffic types [VSAN, VMOTION, VIRTUALMACHINE, MANAGEMENT, NFS, VDP, HBR, FAULTTOLERANCE, ISCSI]
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_vsan.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_vsan.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_vmotion.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_vmotion.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_vm.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_vm.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_management.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_management.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_vdp.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_vdp.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_nfs.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_nfs.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_hbr.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_hbr.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_fault.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_fault.value
    }
    nioc {
      traffic_type = var.vcf_instance_demo_vds.nioc_iscsi.traffic_type
      value        = var.vcf_instance_demo_vds.nioc_iscsi.value
    }
    vmnics   = var.vcf_instance_demo_vds.vmnics
    networks = var.vcf_instance_demo_vds.networks
  }
  # Cluster Configuration
  cluster {
    cluster_name = var.vcf_instance_demo_cluster.cluster_name
    # Requires both management and network as a minimum.
    resource_pool {
      name = var.vcf_instance_demo_cluster.resource_pool_management.name
      type = var.vcf_instance_demo_cluster.resource_pool_management.network_type
    }
    resource_pool {
      name = var.vcf_instance_demo_cluster.resource_pool_network.name
      type = var.vcf_instance_demo_cluster.resource_pool_network.network_type
    }
  }
  # PSC Configuration
  psc {
    psc_sso_domain          = var.vcf_instance_demo_psc.psc_sso_domain
    admin_user_sso_password = var.admin_user_sso_password
  }
  # vCentre Configurations
  vcenter {
    vcenter_ip            = var.vcf_instance_demo_vCenter.vcenter_ip
    vcenter_hostname      = var.vcf_instance_demo_vCenter.vcenter_hostname
    license               = var.vcf_instance_demo_license_key.vcenter
    root_vcenter_password = var.root_vcenter_password
    vm_size               = var.vcf_instance_demo_vCenter.vm_size
  }
  #vSAN Configurations
  vsan {
    license        = var.vcf_instance_demo_license_key.vsan
    datastore_name = var.vcf_instance_demo_vSAN.datastore_name
  }
  # ESXi Host Configurations
  host {
    credentials {
      username = var.vcf_instance_demo_esx_host1.credentials.username
      password = var.esx_host1_password
    }
    ip_address_private {
      subnet     = var.vcf_instance_demo_esx_host1.ip_address_private.subnet
      ip_address = var.vcf_instance_demo_esx_host1.ip_address_private.ip_address
      gateway    = var.vcf_instance_demo_esx_host1.ip_address_private.gateway
    }
    hostname    = var.vcf_instance_demo_esx_host1.hostname
    vswitch     = var.vcf_instance_demo_esx_host1.vswitch
    association = var.vcf_instance_demo_esx_host1.association
  }
  host {
    credentials {
      username = var.vcf_instance_demo_esx_host2.credentials.username
      password = var.esx_host2_password
    }
    ip_address_private {
      subnet     = var.vcf_instance_demo_esx_host2.ip_address_private.subnet
      ip_address = var.vcf_instance_demo_esx_host2.ip_address_private.ip_address
      gateway    = var.vcf_instance_demo_esx_host2.ip_address_private.gateway
    }
    hostname    = var.vcf_instance_demo_esx_host2.hostname
    vswitch     = var.vcf_instance_demo_esx_host2.vswitch
    association = var.vcf_instance_demo_esx_host2.association
  }
  host {
    credentials {
      username = var.vcf_instance_demo_esx_host3.credentials.username
      password = var.esx_host3_password
    }
    ip_address_private {
      subnet     = var.vcf_instance_demo_esx_host3.ip_address_private.subnet
      ip_address = var.vcf_instance_demo_esx_host3.ip_address_private.ip_address
      gateway    = var.vcf_instance_demo_esx_host3.ip_address_private.gateway
    }
    hostname    = var.vcf_instance_demo_esx_host3.hostname
    vswitch     = var.vcf_instance_demo_esx_host3.vswitch
    association = var.vcf_instance_demo_esx_host3.association
  }
  host {
    credentials {
      username = var.vcf_instance_demo_esx_host4.credentials.username
      password = var.esx_host4_password
    }
    ip_address_private {
      subnet     = var.vcf_instance_demo_esx_host4.ip_address_private.subnet
      ip_address = var.vcf_instance_demo_esx_host4.ip_address_private.ip_address
      gateway    = var.vcf_instance_demo_esx_host4.ip_address_private.gateway
    }
    hostname    = var.vcf_instance_demo_esx_host4.hostname
    vswitch     = var.vcf_instance_demo_esx_host4.vswitch
    association = var.vcf_instance_demo_esx_host4.association
  }
}

output "sddc-ip" {
  value = vcf_instance.demo.sddc_manager_fqdn
}

Text, text, text…

Vars.tfvars

Finally lets look at the vars.tfvars file. This is where we actually specify our variable values, or those that we are happy to have in plain text in the configuration. This will not include password, license keys etc or any other sensitive data, these should be passed via environment variables.

# Provider variables
cloud_builder_host = "demo-cb02.demo.local"

# SDDC Manager variables
vcf_instance_demo_instance_id                    = "demo-m02"
vcf_instance_demo_dv_switch_version              = "7.0.3"
vcf_instance_demo_skip_esx_thumbprint_validation = true
vcf_instance_demo_management_pool_name           = "demo-m01-np01"
vcf_instance_demo_ceip_enabled                   = true
vcf_instance_demo_task_name                      = "workflowconfig/workflowspec-ems.json"
vcf_instance_demo_sddc_manager_ip_address        = "192.168.1.130"
vcf_instance_demo_sddc_manager_hostname          = "demo-vcf02"
vcf_instance_demo_ntp                            = "10.111.0.74"
vcf_instance_demo_dns_domain                     = "demo.local"
vcf_instance_demo_dns_name_server                = "192.168.1.10"

# Management network variables
vcf_instance_demo_network_management = {
  subnet       = "192.168.0.0/24"
  vlan_id      = "150"
  mtu          = "1500"
  network_type = "MANAGEMENT"
  gateway      = "192.168.0.254"
}
# VM Management network variables
vcf_instance_demo_network_vm_management = {
  subnet         = "192.168.1.0/24"
  vlan_id        = "151"
  mtu            = "9000"
  network_type   = "VM_MANAGEMENT"
  gateway        = "192.168.1.254"
  port_group_key = "VM_Management"
}

# vMotion network variables
vcf_instance_demo_network_vmotion = {
  subnet       = "192.168.2.0/24"
  vlan_id      = "152"
  mtu          = "9000"
  network_type = "VMOTION"
  gateway      = "192.168.2.254"
  include_ip_address_ranges = {
    ip_address_ranges_start = "192.168.2.110"
    ip_address_ranges_end   = "192.168.2.125"
  }
}

# vSAN network variables
vcf_instance_demo_network_vsan = {
  subnet       = "192.168.3.0/24"
  vlan_id      = "153"
  mtu          = "9000"
  network_type = "VSAN"
  gateway      = "192.168.3.254"
  include_ip_address_ranges = {
    ip_address_ranges_start = "192.168.3.110"
    ip_address_ranges_end   = "192.168.3.125"
  }
}

# NSX variables
vcf_instance_demo_nsx = {
  nsx_manager_size  = "medium"
  vip               = "192.168.1.126"
  vip_fqdn          = "demo-m01-nsx02"
  transport_vlan_id = 154
  nsx_manager_a = {
    hostname = "demo-m01-nsx02a"
    ip       = "192.168.1.127"
  }
  nsx_manager_b = {
    hostname = "demo-m01-nsx02b"
    ip       = "192.168.1.128"
  }
  nsx_manager_c = {
    hostname = "demo-m01-nsx02c"
    ip       = "192.168.1.129"
  }
  ip_address_pool = {
    name = "TEP_Pool" #No spaces!!
    subnet = {
      cidr    = "192.168.4.0/24"
      gateway = "192.168.4.254"
      ip_address_pool_range = {
        start = "192.168.4.90"
        end   = "192.168.4.110"
      }
    }
  }
  overlay_transport_zone = {
    zone_name    = "demo-m01-overlay-tz"
    network_name = "demo-m01-overlay"
  }
}
# vDS variables
vcf_instance_demo_vds = {
  dvs_name = "demo-m01-cl01-vds01"
  mtu      = 9000
  nioc_vsan = {
    traffic_type = "VSAN"
    value        = "HIGH"

  }
  nioc_vmotion = {
    traffic_type = "VMOTION"
    value        = "LOW"
  }
  nioc_vm = {
    traffic_type = "VIRTUALMACHINE"
    value        = "HIGH"
  }
  nioc_management = {
    traffic_type = "MANAGEMENT"
    value        = "NORMAL"
  }
  nioc_vdp = {
    traffic_type = "VDP"
    value        = "NORMAL"
  }
  nioc_nfs = {
    traffic_type = "NFS"
    value        = "NORMAL"
  }
  nioc_hbr = {
    traffic_type = "HBR"
    value        = "NORMAL"
  }
  nioc_fault = {
    traffic_type = "FAULTTOLERANCE"
    value        = "NORMAL"
  }
  nioc_iscsi = {
    traffic_type = "ISCSI"
    value        = "NORMAL"
  }
  vmnics = ["vmnic0",
    "vmnic1"
  ]
  networks = [
    "MANAGEMENT",
    "VSAN",
    "VMOTION"
  ]

}
#Cluster variables
vcf_instance_demo_cluster = {
  cluster_name = "demo-m01-cl01"
  resource_pool_management = {
    name         = "management-resources"
    network_type = "management"
  }
  resource_pool_network = {
    name         = "network-resources"
    network_type = "network"
  }
}
#PSC variables
vcf_instance_demo_psc = {
  psc_sso_domain = "vsphere.local"
}
#vCenter variables
vcf_instance_demo_vCenter = {
  vcenter_ip       = "192.168.1.125"
  vcenter_hostname = "demo-m01-vc02"
  vm_size          = "small"
}
#vSAN variables
vcf_instance_demo_vSAN = {
  datastore_name = "demo-m01-cl01-ds-vsan01"
}

#ESXi variables
vcf_instance_demo_esx_host1 = {
  credentials = {
    username = "root"
  }
  ip_address_private = {
    subnet     = "255.255.255.0"
    ip_address = "192.168.0.121"
    gateway    = "192.168.0.254"
  }
  hostname    = "demo-m01-esx10"
  vswitch     = "vSwitch0"
  association = "demo-m01-dc01"
}
vcf_instance_demo_esx_host2 = {
  credentials = {
    username = "root"
  }
  ip_address_private = {
    subnet     = "255.255.255.0"
    ip_address = "192.168.0.122"
    gateway    = "192.168.0.254"
  }
  hostname    = "demo-m01-esx11"
  vswitch     = "vSwitch0"
  association = "demo-m01-dc01"
}
vcf_instance_demo_esx_host3 = {
  credentials = {
    username = "root"
  }
  ip_address_private = {
    subnet     = "255.255.255.0"
    ip_address = "192.168.0.123"
    gateway    = "192.168.0.254"
  }
  hostname    = "demo-m01-esx12"
  vswitch     = "vSwitch0"
  association = "demo-m01-dc01"
}
vcf_instance_demo_esx_host4 = {
  credentials = {
    username = "root"
  }
  ip_address_private = {
    subnet     = "255.255.255.0"
    ip_address = "192.168.0.124"
    gateway    = "192.168.0.254"
  }
  hostname    = "demo-m01-esx13"
  vswitch     = "vSwitch0"
  association = "demo-m01-dc01"
}

# Licence variables
vcf_instance_demo_license_key = {
  nsx     = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
  vcenter = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
  vsan    = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
  esxi    = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
}

Test, text, text… Codeium?

Now we have our code, lets see it in action!

The complete latest code can be found here on my GitHub Repo.

Here is the live stream of the full session in Las Vegas if you missed out!

youtube …..

As always, thanks for reading!

If you like my content, consider following me on Twitter so you don’t miss out!

Follow @vStephanMcTighe