OneFuse Terraform Provider with vSphere

OneFuse, Terraform

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:

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:

  1. Statically configure them into the configuration
  2. Use a variables file and pass them in as inputs
  3. Use a .tfvars file 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 utilize 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.

Questions or comments? Visit our

Comments are closed.

Skip to toolbar