OneFuse Terraform Provider with vSphere
Editor's note (2026): The methodology described in this post is what I now call Decisions as Code. Property Toolkit was the OneFuse implementation of the same idea. See "Decisions as Code" for the current framing.
In previous articles, I covered using the OneFuse Foundations Modules (Naming, IPAM, DNS, & Active Directory) within Terraform Configurations. These articles covered using them standalone. In this article, we are going to look at using them with the Terraform vSphere Provider.
OneFuse Terraform Provider with vSphere
If you haven’t yet set up OneFuse, you will want to visit the OneFuse Guide and setup OneFuse and the associated policies. You will also want to familiarize yourself with the OneFuse Terraform Provider and Module.
Terraform Configurations for all the examples covered in this and other articles are available on our public Git repo at GitHub.
OneFuse Configuration
In this example I’m going to use the OneFuse Terraform Module. I’m not going to cover all the details for configuring the OneFuse Provider. You can find details on how to configure the OneFuse provider in any of the following Terraform articles:
- Terraform with OneFuse: Naming
- Terraform with OneFuse: IPAM
- Terraform with OneFuse: DNS
- Terraform with OneFuse: Active Directory
- Terraform with OneFuse: OneFuse Terraform Module
We will be using all the OneFuse foundations modules in this example.
module "onefuse" {
source = "git::https://github.com/CloudBoltSoftware/terraform-module-onefuse.git?ref=v1.2-beta.1"
name_policy = var.name_policy
ipam_policy = var.ipam_policy
ad_policy = var.ad_policy
dns_policy = var.dns_policy
template_properties = var.template_properties
}
We will need to provide the name of the policy to use for each of the modules. This can be done in one of three ways:
- Statically configure them into the configuration
- Use a variables file and pass them in as inputs
- Use a
.tfvarsfile to hold the values
For the template_properties the three above options are also valid. In my environment, I choose to use a .tfvars file so I can remain flexible, but not have to type in the values each and every time. For template_properties will contain all name/value pairs for every module simplifying the configuration.
Below is my variables file:
variable "onefuse_scheme" {
type = string
default = "https"
}
variable "onefuse_address" {
type = string
}
variable "onefuse_port" {
type = string
}
variable "onefuse_user" {
type = string
}
variable "onefuse_password" {
type = string
}
variable "onefuse_verify_ssl" {
type = bool
default = false
}
// Begin module inputs
variable "template_properties" {
type = map
}
variable "name_policy" {
type = string
default = ""
}
variable "ad_policy" {
type = string
default = ""
}
variable "ipam_policy" {
type = string
default = ""
}
variable "dns_policy" {
type = string
default = ""
}
You can set your environment in the way that works best for you. Below is how my environment is setup:
Environment Variables:
- onefuse_user
- onefuse_password
Environment.tfvars file:
- onefuse_address
- template_properties
Configuration.tfvars file
- All policies
This may require some explaining. I connect to multiple different OneFuse servers for different reasons. I have an environment for development, testing, demos, blogging, and a few others. For each of these environments I maintain a .tfvars file. These files contain the server address and a master list for all the .tfvars I would use in that environment.
I then have a .tfvars file in each of my configuration folders for each environment. This typically contains the policies I want to call for that configuration. When I apply a configuration, I specify both files at the command line and I end up with all the inputs needed to successfully run the configuration.
Below is my environment .tfvars file
template_properties = {
"nameEnv" = "p"
"nameOS" = "w"
"nameDatacenter" = "por"
"nameApp" = "ap"
"nameLocation" = "atl"
"nameGroup" = "pp"
"ouGroup" = "PiedPiper"
"ouEnv" = "PRD"
"dnsSuffix" = "infoblox851.company.com"
"sgEnv" = "prod"
"username" = "sidtestuser"
"firstname" = "sidtest"
"lastname" = "user"
"domain" = "company.com"
"folderGroup" = "PiedPiper"
"folderEnv" = "PROD"
"memoryGB" = "1"
"cpuCount" = "1"
}
onefuse_address = "sid-onefuse-blog.company.com"
This is great for testing, but it doesn’t scale for production use. I will cover how I use the OneFuse Property Toolkit to help simplify and drive all the template properties in a future article.
My plan specific .tfvars has the following:
name_policy = "machine"
ad_policy = "prod"
ipam_policy = "atlprod"
dns_policy = "prod"
Between the .tfvars files, the defaults configured in my variables file, and my environment variables I have everything I need covered.
Terraform Files
Before we get into the vSphere configuration I want to talk a bit about the .tf files I use. One thing I find very handy in Terraform is that I can have as many .tf files as I want and it handles parsing them and bringing them all together.
If I’m not using modules for my configuration, I use the following file structure. You will find this same structure in the examples on our GitHub repo.
- main.tf – I typically put my OneFuse configurations here, but you could them in a onefuse.tf and place the providers in here as opposed to the providers.tf.
- providers.tf – I put all my providers configuration in here.
- properties.tf – Here is where I do all my OneFuse Property Toolkit configuration as well as local variables.
- variables.tf – All variable inputs
- output.tf – All outputs
- vsphere.tf (aws.tf, azure.tf, gcp.tf, etc) – Platform specific configurations. I may even break down further if I’m doing large amounts of configurations.
I find doing this help me easily troubleshoot and find what I’m looking for easily. This works well for me for testing, building new configurations, etc however most production environments are far more elaborate than this. I’m just sharing this as a reference for how my environment is configured for this example.
vSphere
Below is the vSphere configuration I used for this example.
### vSphere Machine Deployment ###
#Data Sources
data "vsphere_datacenter" "dc" {
name = "SovLabs"
}
data "vsphere_datastore_cluster" "datastore_cluster" {
name = "SovLabs_XtremIO"
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_compute_cluster" "cluster" {
name = "Cluster1"
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_network" "network" {
name = module.onefuse.network
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_virtual_machine" "template" {
name = "CentOS7"
datacenter_id = data.vsphere_datacenter.dc.id
}
#Virtual Machine Resource
resource "vsphere_virtual_machine" "vm" {
// Use OneFuse generated name for VM hostname and domain
name = module.onefuse.hostname
resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
datastore_cluster_id = data.vsphere_datastore_cluster.datastore_cluster.id
num_cpus = "1"
memory = "2048"
guest_id = data.vsphere_virtual_machine.template.guest_id
scsi_type = data.vsphere_virtual_machine.template.scsi_type
network_interface {
network_id = data.vsphere_network.network.id
adapter_type = "vmxnet3"
}
disk {
label = "disk0"
size = data.vsphere_virtual_machine.template.disks.0.size
eagerly_scrub = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
}
clone {
template_uuid = data.vsphere_virtual_machine.template.id
customize {
linux_options {
host_name = module.onefuse.hostname
domain = module.onefuse.dns_suffix
}
network_interface {
ipv4_address = module.onefuse.ip_address
ipv4_netmask = 24
}
ipv4_gateway = module.onefuse.gateway
}
}
}
If you look through the configuration you will see references to module.onfuse.hostname, module.onfuse.ip_address, module.onfuse.gateway, and module.onfuse.network. These are all passed in to the appropriate inputs to be used during the vSphere VM deployment.
Stay tuned in for future articles where I will take this example a bit further with the OneFuse Property Toolkit. We will use Property Toolkit to dynamically supply values for the following:
- template
- cpu
- memory
- netmask
- folder
We will then take a look at creating a module that combines OneFuse, and vSphere for a super simple way to deploy new vSphere VMs in a very repeatable dynamic way.
Want to try OneFuse with Terraform for yourself? Check out the WWT HOL Accelerating Terraform with OneFuse.