Moving forward with PowerCLI instead of InSpec-VMware


If you use the VMware ecosystem in your day to day job, you may have seen the incubation InSpec project inspec-vmware and got excited about the possibilities of running InSpec tests against your VMware Software Defined Data Centers (SDDC)s and VMware on AWS.

If you haven’t seen the inspec-vmware project, imagine the ability to audit/validate your complete VMware stack multiple times per hour, instead of that one time your audit team(s) required you to. This opens up a huge opportunity for both you and your VMware administrators for the consistency and reporting you need in your environments.

Switching to PowerCLI

If you saw the original implementation, I’m here to say that we have decided to move away from this original iteration and on to something that is much better.

After strong debate and consideration, we realized that the inspec-vmware project as it exists wouldn’t give us the flexibility and coverage we want with InSpec in the VMware stack. With this in mind we have decided to move away from the current implementation to using PowerShell and PowerCLI.

Before we go any farther, if you don’t know, PowerShell and PowerCLI both work on RHEL and Debian based operating systems. Yes, I’ll say that again, PowerShell and PowerCLI both work on non-Windows Operating Systems. Bringing the power of PowerShell to other OSs and ecosystems is a huge achievement for the PowerShell community.

InSpec VMware Resource Pack

A resource pack is a way for us to plug into other APIs from the InSpec standpoint. We have multiple resource packs now, and this inspec-vmware is a rewrite of one of our original three. If you would like a simple way to start with this integration we have created an example repository you can just “run it.”

With the use of the inspec-vmware resource pack and an InSpec version greater than 2.2.31 you can now audit VMware platforms using the powercli_command InSpec resource.

This custom resource allows you to run arbitrary PowerCLI commands through a local InSpec process, and in turn, validate different settings against the VMware APIs.

In order for this to work, you will need to have PowerCLI and PowerShell installed on where you run this from. Take a look at the inspec-vmware or the inspec-vmware-example repo to get it working on your local machine.

The following example control makes sure that you have the SSH agent turned off on your ESXi host.

control '2-disable-ssh' do
  title 'Disable SSH'
  impact 0.5
  desc '
    Disable Secure Shell (SSH) for each ESXi host to prevent remote access to the ESXi shell.
    SSH is only allowed if needed for troubleshooting or diagnostics.
  tsm_ssh_cmd = 'Get-VMhost | Get-VMHostService | Where {$_.Key -eq "TSM-SSH" -and $_.Running -eq $False}'
  describe powercli_command(tsm_ssh_cmd) do
    its('exit_status') { should cmp 0 }
    its('stdout') { should_not be_empty }

If you are familiar with InSpec tests this test may seem confusing to you. In short, this control runs the tsm_ssh_cmd that we defined using PowerCLI. That command will only have output if TSM-SSH is not running (i.e. $_.Running equals $False).

Running this command against one of your ESXi hosts in PowerShell will help clear up any confusion. Here is an example of the output:

PS > Connect-VIServer <YOUR ESXi HOST> -User root -Password <PASSWORD>
PS > Get-VMhost | Get-VMHostService | Where {$_.key -eq "TSM-SSH" -and $_.running -eq $True}
PS > Get-VMhost | Get-VMHostService | Where {$_.key -eq "TSM-SSH" -and $_.running -eq $False}
Key                  Label          Policy Running Required
---                  -----          ------ ------- --------
TSM-SSH              SSH          off False    False

As you can see, output is only generated when the Where clause evaluates to true. Knowing this, we can use the stdout matcher here to verify that output is present (since we know that no output means TSM-SSH is running).

Chef Automate Reporting

In addition to viewing the results of InSpec locally you can also send the results to Chef Automate. To do this, first you will need to create a json file like the following example:

  "reporter": {
      "automate" : {
          "stdout" : "false",
          "url" : "https://YOUR_AUTOMATE_SEVER_FQDN/data-collector/v0",
          "token" : "YOUR_AUTOMATE_ADMIN_TOKEN",
          "node_name" : "esxi-41",
          "node_uuid" : "97d050b2-1103-48e5-af54-4f1d1c978074",
          "verify_ssl" : false

You should change a few of the options around to match your environment. Second, if you decide to run this against your ESXi hypervisor you will need to create a UUID for Compliance to identify it against. The easiest way to get a UUID is to run the following ruby command:

$ ruby -r securerandom -e 'puts SecureRandom.uuid'

After these changes, you can run it using the following command example, and you should see it report in the Compliance section of Chef Automate. You should verify that your node_name, and your viserver attribute setting match per the ESXi host you want to run this against and have it continually validate those settings. You can run this as many times as you’d like, getting a nice visualization in a centralized location.

$ cd powershell-inspec
$ inspec exec . --json-config esxi.json -t vmware://USERNAME@VISERVER --password YOUR_PASSWORD

Lets Connect

I’d love to hear any feedback you might have about any or all of these changes. The Chef VMware community hangs out on the VMware{code} slack team, in the channel #chef. Don’t hesitate to come round and say hi, or reach out directly to me (@jj) if you have any questions or feedback. Looking forward to speaking with you!

Author JJ Asghar

JJ works with Strategic Technical Alliances at Chef Software making integrations work with Chef, Habitat, and InSpec. He works on everything from Azure, VMware, OpenStack, and Cisco with everything in between. He also heads up the Chef Partner Cookbook Program to make sure customers of Chef and vendors get the highest quality certified cookbooks. He grew up and currently lives in Austin, Texas.