Summary
This tutorial will show you how to apply one or more licenses to vCenter through the use of Terraform. This can be expanded on to create a module that can be used across multiple vSphere environments.
Structure
First of all, we are going to create a folder called configure_licensing. In this folder we create the following files
filename | purpose |
---|---|
variables.tf | definitions of the variables required (i.e. license keys to apply) |
main.tf | the terraform definition that will apply the license keys |
provider.tf | specifies the provider to use (in this case the vSphere provider) |
provider_variables.tf | contains a list of variables with default values for the provider |
outputs.tf | Specifies information to output once an apply operation has been completed successfully |
You could in theory combine the provider.tf and provider_variables.tf files, but my personal preference is to keep them seperate. One file defines the provider to use whilst the other defines what you need to pass in to enable the provider. In terms of file content, it is actually quite light!
provider_variables.tf
# Variables section for vSphere connectivity variable "vsphere_server" { description = "fqdn for the vsphere server for the environment" default = "testvc.automationcore.com" } variable "vsphere_user" { description = "user with sufficient rights to vsphere server for the environment" default = "administrator@vsphere.local" } variable "vsphere_password" { description = "vsphere server password for the environment" default = "topsecret123!" } variable "allow_unverified_ssl" { description = "specify whether we can use unverified ssl certificates" default = true }
provider.tf
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 = var.allow_unverified_ssl }
variables.tf
# The licenses to add variable "licenses" { type = list(string) }
main.tf
resource "vsphere_license" "licenseKey" { count = length(var.licenses) license_key = var.licenses[count.index] }
outputs.tf
output "edition_key" { value = vsphere_license.licenseKey.*.edition_key } output "total" { value = vsphere_license.licenseKey.*.total } output "used" { value = vsphere_license.licenseKey.*.used } output "name" { value = vsphere_license.licenseKey.*.name }
Let’s concentrate on the variables.tf, main.tf and outputs.tf files.
variables.tf
As you can see we have declared a variable called licenses. The type is list(string) which means it expects to recieve one or more license keys, wrapped in quotes and comma seperated. We wrap the entire entry in ‘[]‘ brackets. As an example, we would pass in something like the following
[“12345-abcde-fghjk-67890-qwerf”, “67890-qwerf-12345-01CU4-987VC”]
main.tf
As you can see we are declaring a resource type of vsphere_license.licenseKey. According to the documentation, there are two arguments
argument | description | required |
---|---|---|
license_key | specifies the license key that you want to add to vSphere | true |
labels | allows you to specify key/value pairs that can be allocated to the license key in the form of a tag | false |
I am only going to bother specifying the required argument. The documentation provides an example of how to add a license key, however we want to allow for adding multiple keys. So how do we do this? Quite simply actually! Lets break it all down.
resource "vsphere_license" "licenseKey" { count = length(var.licenses) license_key = var.licenses[count.index] }
count = length(var.licenses)
Remember how we declared our licenses variable type as a list(string)? Since we have declared it as a list, we can use a built in method to find the length of the list, or to think of it differently, the size of the list. If we passed in two values (two license keys) into this variable, then the length will be 2. Count will be set to the length.
license_key = var.licenses[count.index]
If you have any experience with programming in any language then you may recognise the following style of syntax (this is a syntax example, not workable code)
for each (var fruit in fruitbowl) { echo "This is a " + fruit }
The idea is that if there are 5 items of fruit in the fruitbowl, we will echo out “This is a ” followed by a type of fruit, five times; a bit like this
var fruitbowl = ["banana","orange","apple","pear","grape"] for each (var fruit in fruitbowl) { echo "This is a " + fruit } example output: This is a banana This is a orange This is a apple This is a pear This is a grape
The way that our license_key = var.licenses[count.index] line is processed, is actually very similar to my fruitbowl example (despite to very different syntax!). Terraform will set license_key equal to each of the items in our list(string). I know, it really doesn’t look like it would considering the syntax. Think of it as being executed something like this
licenses = ["12345-abcde-fghjk-67890-qwerf", "67890-qwerf-12345-01CU4-987VC"] for each (var license in licenses) { resource "vsphere_license" "licenseKey" { license_key = license } }
Which would execute something like this on the first iteration
for each (var license in licenses) { resource "vsphere_license" "licenseKey" { license_key = "12345-abcde-fghjk-67890-qwerf" } }
and like this on the second iteration
for each (var license in licenses) { resource "vsphere_license" "licenseKey" { license_key = "67890-qwerf-12345-01CU4-987VC" } }
So, Terraform creates the resource one at a time. Simple, hey?
outputs.tf
As you can see we are declaring a number of outputs that we would like sent to the console when the application has been successful. How do we know these exist? They are documented in the attributes reference section of the documentation. Each of the outputs is assigned a name. This enables you to reference and use the output value in another script later on. Because we are going to accept multiple license keys as input we have to format each output to contain a ‘*’ character to enable the value of each iteration to be output.
Execution
Lets run a terraform plan and pass in some license keys. Create a definitions file with the license keys that you want to register, like this [editor: why? because it is easier than trying to specify on the command line!]
definitions
# License keys to register with the vCenter server licenses = ["abc-def-ghj-klm-npq", "123-456-789-abcd-efgh"]
Now, lets run a terraform plan and have a look at what is going to change. We will pass the definitions file to terraform plan, as well request that the plan output be saved to disk.
Once we happy with the changes, we can run terraform apply, passing in the plan. As you can see, the outputs that we requested are shown at the end of a successful execution.