Deploy vSphere VMs with Ansible!

In a previous post, we covered how to create a virtual machine from a VM template in vSphere using Python and the REST API as an example of service-agnostic methods to invoke infrastructure resources.

VMware's PowerCLI is a fantastic tool, but it's not for me. Tweaking or porting functionality from PowerCLI to other languages beyond Windows and PowerShell isn't supported. Technology professionals with more than a few years of experience are leery of code portability issues; standard hardware architectures today are the results of consolidation efforts and caused some quite painful transition points. Change safety features like idempotency or context awareness are important to me; I prefer the approach of "check parameters, check destructiveness, execute, test."

Engineers develop linguistic preferences as part of a normal progression throughout their careers. Bash/Zsh/Python/Perl and JSON/YAML/XML appear more intuitive to me as universal formats to store artifacts and execution code. BASIC-style languages like PowerShell/CLI are not for everybody.

It's possible to use Ansible to manage and deploy Virtual Machines now - the previously covered Python code leverages the same RESTful API as the Ansible modules. The Ansible modules shift responsibility for code maintenance away from internal teams. Let's not forget the cost of writing and maintaining custom code:

Automation Value Proposition

Let's take a look. We need to install the Ansible "Collection" to leverage the REST API (this does require the Python package aiohttp:

 1ansible-galaxy collection install vmware.vmware_rest  
 2Starting galaxy collection install process  
 3Process install dependency map  
 4Starting collection install process  
 5Installing 'vmware.vmware_rest:2.2.0' to '/root/.ansible/collections/ansible_collections/vmware/vmware_rest'  
 6Downloading to /root/.ansible/tmp/ansible-local-346454pqg9aobo/tmpi1o29dho  
 7vmware.vmware_rest (2.2.0) was installed successfully  
 8Installing 'cloud.common:2.1.2' to '/root/.ansible/collections/ansible_collections/cloud/common'  
 9Downloading to /root/.ansible/tmp/ansible-local-346454pqg9aobo/tmpi1o29dho  
10cloud.common (2.1.2) was installed successfully  

First, let's plan where automation will deploy workloads. Good work starts with good data - Ansible combines with a popular template tool (Jinja), enabling automation engineers to compile "pretty" reports from variables we collect during the execution phase:

The playbook will help any planning efforts with consistent infrastructure. At work, I'd recommend rendering an HTML page with these artifacts (Jinja can do that as well) periodically with a CI tool and publishing it to a web server for other teams to reference.

Let's use that information to deploy a virtual machine:

Correctly setting the session_timeout parameter in the playbook is critical. VM Deployment times depend on storage backing; the default timeout is 300 seconds. Deployment timeouts require adjustment to the equipment they live on - I set it to 1200 seconds to accommodate spinning disks.

This playbook is parameterized, with variables identified by double curly brackets,  {{ variable_name }}. Ansible Playbook examples don't always provide what output the code will expect, a consistent issue with community-generated code.

Ansible supports variable injection from an external file or the command line; the best way to manage these input variables for self-service is to use file-based inputs. CI tools ship with APIs that allow you to invoke a pipeline with a JSON payload, and this method gives you an easy way to convert back and forth. I have provided an example JSON document to show what format the playbook wants.

To invoke extra variables in Ansible, use the ext-vars feature:

1ansible-playbook build_vm.yml "@parameters.json"

Jenkins has a parameter injection feature that makes this consumable as an end user as well:

Jenkins Parameterization

Consumers perceive infrastructure's quality with a heavy bias towards convenience. We should construct easy ways to provision resources and enable creativity to boost positive perception of infrastructure services. Ansible's vmware_rest module combines with an execution engine like Jenkins to create an open method for deploying Virtual Machines, a pivotal step towards making infrastructure appealing.