Randomising vSphere Datastore Selection With Terraform | Writing about tech and anything else I find interesting

Randomising vSphere Datastore Selection With Terraform

This week I ran into a customer who wasn’t using datastore clusters in their vSphere environment and was looking for ways to randomise the placement of workloads.

Consider the following code.

# Declare variables
variable datastores {
type = list(string)
default = [
"hl-core-ds01",
"hl-core-ds02",
"hlcoresx01-local",
"vsanDatastore"
]
}
# Discover data sources
data vsphere_datacenter "this" {
name = "Core"
}
data vsphere_datastore "this" {
count = length(var.datastores)
datacenter_id = data.vsphere_datacenter.this.id
name = var.datastores[count.index]
}
view raw main.tf hosted with ❤ by GitHub

Ignoring that I’ve dropped variables, outputs and data sources all into a single file, what can you see? A selection of datastores declared as a variable that we are going to retrieve the ids for.

The next step is to find a way to randomise these. Enter the random_shuffle resource type.

# Show random function
resource random_shuffle "this" {
input = data.vsphere_datastore.this.*.id
result_count = 1
}
# Write output
output datastore_id {
value = random_shuffle.this.result
}
view raw main.tf hosted with ❤ by GitHub

The random_shuffle resource will return a list of values, based on the result_count value that you specify. This gives some nice flexibility, such as the situation where you were intending to deploy multiple machines, and wanted a randomised datastore placement for each of them.
To achieve that you could do something like this.

# Declare variables
variable datastores {
type = list(string)
default = [
"hl-core-ds01",
"hl-core-ds02",
"hlcoresx01-local",
"vsanDatastore"
]
}
# Discover data sources
data vsphere_datacenter "this" {
name = "Core"
}
data vsphere_datastore "this" {
count = length(var.datastores)
datacenter_id = data.vsphere_datacenter.this.id
name = var.datastores[count.index]
}
# Show random function
resource random_shuffle "this" {
input = data.vsphere_datastore.this.*.id
result_count = var.virtual_machine_count
}
# Provision VMs
resource vsphere_virtual_machine "this" {
count = var.virtual_machine_count
resource_pool_id = data.vsphere_compute_cluster.this.resource_pool_id
datastore_id = random_shuffle.this.result[count.index]
...
}
view raw main.tf hosted with ❤ by GitHub

Now we are starting to cook with gas!

In closing, there are a few things to be aware of when using any of the random resources. They don’t regenerate every time you perform a plan/apply. You can choose to taint (terraform taint random_shuffle.this) to have the randomness be generated, or you can tie the random generation to another object such as your list of datastores as a keeper. Changes to the list of datastores would regenerate the result of the random_shuffle. Bear in mind that the downstream effect of this could be to change the placement of your existing virtual machine disks.

Happy Terraforming!