Deploying vSphere Virtual Machines as Code

In this post, we'll walk through a simple example of cloning a vSphere VM template using Terraform.

Terraform is an infrastructure as code tool that can used to deploy resources within several types of environment. At the time of this writing, Terraform is capable of deploying resources as code to 719 providers. Some of the most common being VMware, Microsoft Azure, and AWS. A complete list can be found here:

The code referenced in the blog can be downloaded here:

Contribute to rnemeth90/terraform development by creating an account on GitHub.

To get started, download the code and open the,, and variables.tfvars files in your IDE of choice. If you do not currently have an IDE, I suggest using Visual Studio Code. It is free of charge, cross platform (Windows, Linux, macOS), and is extremely feature rich. Get it here:

Visual Studio Code - Code Editing. Redefined

Once you have the files open, take a look at the file. This is where we will define the various resources that we want to deploy. In this case, we will be deploying a new VM by cloning a VM template in vCenter.

At the top of the file, we need to tell terraform what type of provider we will be working with, and how we can connect to it. This can done by adding a "provider" tag, and then any required parameter in the {} braces. The value for the "user", "password", and "vsphere_server" parameters all begin with "var.". This tells terraform that the value of these parameters are each referencing a variable.

The user, password, and vsphere_server tags reference variables are stored in our file:

The terraform syntax is fairly intuitive/obvious, so I won't be going over it in detail here. However, any parameters that are likely to change often should be stored in the file. Look at the example files you downloaded to get a better understanding. When referencing variables from a file in the (definition) file, the value needs to begin with "var." and then the name of the variable. An example in this case would be: "${var.vsphere_datastore_cluster}"

There are certain things that terraform needs to know about the vSphere environment before deploying the VM. A few examples are the destination network to connect the VMnic to and the destination datastore or datastore cluster. These resources are defined as 'data' blocks in the terraform file.

So far, within the file, we have a provider block, which defines the provider we are working with and any required parameters for interacting with the provider. We also have several 'data' blocks, that typically gather resources about the environment. The 'resource' block is where we actually take all of the values gathered in the data blocks, and other variables, and define the resource we are deploying.

You can see that within the 'resource' block, we are able to reference variables (var) as well as data blocks (data).

Now that you have a basic understanding of the terraform files and syntax, let's take a look at how to actually use them to create a new VM. First, you'll need to have terraform installed. You can simply Google and download the installer. However, I like to use Chocolatey. Chocolatey is a software package manager for Windows that can be called from the cmd line. It's similar to apt or yum in Linux. You can install Chocolatey by opening a PowerShell session (as admin) and running this scriptblock:

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(''))

Now that you have Chocolatey installed, install terraform using the following command:

choco install terraform -y

Easy, right? :)

Now, in the PowerShell console, browse to the directory where you downloaded the terraform files earlier. Type in:

terraform init

This will tell the terraform engine to download the necessary providers referenced in your file. Now, type in:

terraform plan

You should be prompted to type in the value for several of your variables:

Great! If you have gotten this far, terraform can interact and read your .tf files and you likely don't have any syntax issues.

Wouldn't it be nice if we didn't have to type in the values for all of those variables? Well, terraform has an answer for that as well. In the repository files that you downloaded, you should have a variables.tfvars file. You can populate this file with the values for your variables, and then we'll tell terraform that this file has those values. Here is an example of my .tfvars file (without the password or datacenter populated. Though, these variables are required.)

Once you have the file populated with the values for your variables, type in:

terraform plan -var-file="variables.tfvars"

You should receive a lot of green output in your console. Pay particular attention to this line:

Now that we know the deployment will likely be successful (by "planning" it), we can deploy the resource. To do this, simply replace "plan" with "apply" in the command above, like so:

terraform apply -var-file="variables.tfvars"

You will be asked if you want to perform these action. Type in yes and hit enter.

Allow some time for the deployment to complete. This will depend on the size of the template and the performance of your vSphere environment.

comments powered by Disqus