Automating and Enforcing a Consistent vSphere Configuration

It’s always a good idea to enforce consistency for any environment as it leads to a predictable stack that better aligns architecture to reality. As a bit of a self-challenge, I wanted to write a set of PowerShell scripts that would use a defined list of configuration state values to walk through my vSphere environment and correct any deviations from what was declared to be normal. This seemed especially important for my lab, which is in an ever-shifting state. Additionally, the use of raw PowerShell (and PowerCLI cmdlets) meant that I didn’t need to install or configure anything else – basically, a freebie lab tool. And, well, it was sort of fun to tinker with. 🙂

I borrowed the Engine code from my Grafana repo and re-purposed it for a lab config. Having a general-purpose Engine to run job scripts seemed like a simple way to start things off, although it doesn’t scale to anything meaningful. The Engine will fire off a series of VMware job scripts that each have one purpose. Each job file checks the Vars data to determine the desired state of the environment (similar to what I normally use with a JSON or YAML file).

At this time, the jobs scripts defined are as follows:

  • Remove VM limits and reservations (but it will purposefully error out on protected service VMs, such as NSX Edges)
  • Remove ISO or connected CD-ROMs
  • Set host DNS entries
  • Set cluster DRS settings
  • Set host NTP entries
  • Configure the host SSH service
  • Set host syslog setting

If you’d like to use my code, it’s freely available on GitHub for your convenience.


Automatically Running the Engine

Although I could fire off the Engine on an ad-hoc basis, I wanted some automated method to make sure it ran. I also didn’t want to introduce anything beyond PowerShell and PowerCLI, so I looked to Windows Server for an answer.

What I end up doing is running a Scheduled Task on a utility server in the lab which runs the Engine on an hourly basis. The Engine calls a number of job scripts to perform specific jobs in the environment – such as setting NTP, Syslog, or removing ISOs based on what’s described in the Vars file. The service account that runs the task has administrative authority over the vSphere environment, negating the need to provide credentials anywhere in the code. I consider that a plus, but if you need unique credentials for different jobs, you could split the jobs into multiple Engines and assign them different service accounts.

Today, the jobs will set the configuration values to match the Vars file blindly. That is, they don’t check to see if work should be done, it is simply done regardless. In a more perfect world, I’d have the jobs check the values first, and then only make changes if necessary. Similar to Ansible, really. This is a goal for my next round of updates to the repository. I also understand that I’m nothing special when it comes to PowerShell, so PRs with better ways to perform the work or entire forks with improvements would be a delight to see. 🙂

If you want to do something similar but with Puppet, check out the vCenter module on the Forge or via GitHub. It was recently updated to version 0.6.0 after laying stagnant for quite some time.