I have been hearing a lot about Terraform lately and so I decided to check it out myself. First of all, the installation was fairly simple. It is a single executable binary which is zipped and available for download from their official website here.
All you need to get started is a Virtual Machine (Terraform can run on Linux/Windows and/or MAC variants) that can talk to your vSphere infra on port 443 and an user account with read/write access to its APIs. In this blog, we will use an Ubuntu virtual machine.
Once you have the downloaded file ready, copy it to a directory path from where you would like to run the terraform commands from. Unzip it and you will have the binary ready to begin playing around with.
Now that the utility is installed, we will need to initialize it with feeding information about the data source that we intend to connect to. We will do with the help of state files that has the extension .tf. Terraform uses HCL as the framework which Hashicorp rightfully holds proprietorship to. The two main files that we would need at this moment would be main.tf, which talks about the data source that we intend to connect to, resources that we intend to deploy and every other related information, and variables.tf, which declares variables that we use in main.tf. These files can be created using any file editor. For this blog, we will use the vi editor to do so. Firstly, let me define the variables. You can use the code below to do so.
variable "vsphere_user" { default = "XXX@vsphere.local" } variable "vsphere_password" { default = "XXXXXX" } variable "vsphere_server" { default = "vCenter-FQDN" }
Now that we have defined variables, it is time to create the main.tf file that terraform uses to initialize the plugin. This works based on providers. You can have one terraform utility to connect to multiple providers, there by allowing you to manage heterogeneous environments at once. Examples would be GCP,AWS,Azure,VMware. For the sake of this article, we would focus on the vSphere provider.
provider "vsphere" { user = var.vsphere_user password = var.vsphere_password vsphere_server = var.vsphere_server # If you have a self-signed cert allow_unverified_ssl = true }
At this point we have the necessary files to initiate the plugin and to do so, we simply will have to run “terraform init” and it will look for the state files in the installation directory. Hence it is recommended to run this command from the installation directory so that you don’t have to explicitly state the directory along with the command.
Once you have initialized, the output should let you know the provider version that has got updated.
Time to get the actual work done now 🙂 Let us update the main provider file with the resources that we intend to create and get going real quick !! Now let us update the data center name that is already present to the main file and see how terraform responds.
Now, after updating the main.tf, you will have to run “terraform apply” for it to update the changes. The output will be something of this sort below.
Note: This doesn’t create the data center, instead fetches the object id of the existing data center to further create resources within the data center.
To create a new data center, you may have to use the below code in the main.tf. For the sake of this article, we will use an existing DC to deploy the VM.
resource "vsphere_datacenter" "datacenter_ref_name" { name = "datacenter_name" }
Before we create a VM, let me list down the VMs currently present in the infra.
To create a VM, you will have to update the main.tf with all information that will be keyed-in if in case it is deployed through UI.
provider "vsphere" { user = var.vsphere_user password = var.vsphere_password vsphere_server = var.vsphere_server # If you have a self-signed cert allow_unverified_ssl = true } data "vsphere_datacenter" "dc" { name = "Datacenter_Name" } data "vsphere_datastore" "datastore" { name = "DataStore Name" datacenter_id = "${data.vsphere_datacenter.dc.id}" } data "vsphere_compute_cluster" "cluster" { name = "ClusterName" datacenter_id = "${data.vsphere_datacenter.dc.id}" } data "vsphere_network" "network" { name = "PortGroupName" datacenter_id = "${data.vsphere_datacenter.dc.id}" } resource "vsphere_virtual_machine" "vm" { name = "terraform-test" resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}" datastore_id = "${data.vsphere_datastore.datastore.id}" num_cpus = 2 memory = 1024 guest_id = "other3xLinux64Guest" network_interface { network_id = "${data.vsphere_network.network.id}" } disk { label = "disk0" size = 20 } }
It is time to hit apply again. By doing so, you will see a long message with all the attribute values filled in and asking you to confirm the create opeartion as shown below.
Enter yes to proceed. The magic begins 🙂
As you can see from the screenshots above, the deployment process has begun and VM is being created.
The VM is now created and powered on. However, it would have booted up into PXE and I do not have PXE setup now. So my provisioning would fail as expected 🙂 However, you can try the same with a PXE server to boot your machine up. There are options to clone from a template which requires some additional attributes to be included in the main file. You can refer to the terraform documentation to know how this is done, here.
Post completion, hitting “terraform destroy” would remove the test vm that was deployed in a jiffy 🙂 Go ahead and give it a try. Let me know how it goes, in the comments section.
Let us keep the learning and un-learning curve headed steadily till the very end, folks. Happy learning.