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] | |
} |
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 | |
} |
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] | |
... | |
} |
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!