How to creates lot of Vms on Vshpere with Terraform

terraform

Many people suffer from creating a lot of virtual machines on vSphere because they need to configure the network, storage, and resources manually. This manual process can increase the error rate. Today, we are going to give you a tutorial on how to create many VMs on vSphere with Terraform.

This script is based on another script created by Cloudmaniac.

First, we need to collect some information about our vSphere, such as:

1- an account capable of creating VMs.

provider "vsphere" {
  user                 = var.vsphere_user
  password             = var.vsphere_password
  vsphere_server       = var.vsphere_host
  allow_unverified_ssl = true
}

2- Data sources like the cluster name (don’t worry, all this information will be put in the variables file).

##### Data sources
data "vsphere_datacenter" "target_dc" {
  name = var.deploy_vsphere_datacenter
}

data "vsphere_datastore" "target_datastore" {
  name          = var.deploy_vsphere_datastore
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_compute_cluster" "target_cluster" {
  name          = var.deploy_vsphere_cluster
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_network" "target_network" {
  name          = var.deploy_vsphere_network
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_virtual_machine" "source_template" {
  name          = var.guest_template
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

3- Now, the best part: creating our VMs.

##### Resources
# Clones a single Linux VM from a template
resource "vsphere_virtual_machine" "Vms_master" {
  count            = length(var.master_ips)
  name             = "${var.guest_name_prefix}-preprod0${count.index + 1}"
  resource_pool_id = data.vsphere_compute_cluster.target_cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.target_datastore.id
  folder           = var.deploy_vsphere_folder
  #firmware         = var.guest_firmware

  num_cpus = var.guest_vcpu
  memory   = var.guest_memory
  guest_id = data.vsphere_virtual_machine.source_template.guest_id

  #scsi_type = data.vsphere_virtual_machine.source_template.scsi_type

  network_interface {
    network_id   = data.vsphere_network.target_network.id
    adapter_type = data.vsphere_virtual_machine.source_template.network_interface_types[0]
  }

  disk {
    label            = "disk0"
    size             = data.vsphere_virtual_machine.source_template.disks[0].size
    eagerly_scrub    = data.vsphere_virtual_machine.source_template.disks[0].eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.source_template.disks[0].thin_provisioned

  }

  disk {
    label       = "disk"
    size        = 60
    unit_number = 1
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.source_template.id

    customize {
      linux_options {
        host_name = "${var.guest_name_prefix}-preprod0${count.index + 1}"
        domain    = var.guest_domain
      }

      network_interface {
        ipv4_address = lookup(var.master_ips, count.index)
        ipv4_netmask = var.guest_ipv4_netmask
      }

      ipv4_gateway = var.guest_ipv4_gateway
      #dns_server_list = [var.guest_dns_servers]
      #dns_suffix_list = [var.guest_dns_suffix]
    }
  }

  boot_delay = 10000

  # Remove existing SSH known hosts as remote identification (host key) changes between deployments.
  provisioner "local-exec" {
    command = "ssh-keygen -R ${self.guest_ip_addresses[0]}"
  }


  lifecycle {
    ignore_changes = [annotation]
  }

After configuring the main Terraform file, we should now configure our variables. You will find a script here. You just need to fill it with the correct information.

Don’t forget to add another file, called ‘variables.tf‘ that indicates the type of each variable.