Normally I frequently use Powershell when it comes to vSphere automation, but lately, I have been wanting to develop tools and scripts that are user-friendly and easily reusable. With those objectives in mind, it is hard to find a better tool than Ansible playbooks.
Ansible playbooks often use ssh for connecting to remote resources to run commands. With vSphere modules for Ansible. the experience is more similar to how powershell connects.
For these ansible playbooks I will be using a play which will grab some basic datacenter info from a vCenter. This module comes from the VMware Rest collection.
Local Playbook
The first example will be the simplest as all the info is contained within the playbook and we will not be using an inventory file. This is a “quick and dirty” approach as utilizing inventory files/var files is far more in line with the repeatable orchestration for which Ansible is known.
Here is my first playbook gatherinfolocal.yml:
---
- name: Gather Datacenter Information from VMware using REST API
hosts: localhost
gather_facts: no
collections:
- vmware.vmware_rest
tasks:
- name: Get Datacenter information
vmware.vmware_rest.vcenter_datacenter_info:
vcenter_hostname: "vnoobcenter.rosalita.lan"
vcenter_username: "administrator@vsphere.local"
vcenter_password: "MyPassword"
vcenter_validate_certs: no
register: datacenter_info
- name: Display datacenter information
debug:
var: datacenter_info
All of the information for the vCenter, including the password, is in the playbook. I probably don’t need to mention how this is less than ideal and not secure.
Hosts is defined as localhost as we are not utilizing an inventory. The module is “vmware.vmware_rest.vcenter_datacenter_info” which utilizes vCenters REST API to pull some datacenter info back. That information is stored in the datacenter_info variable which is then return with debug.
Running this playbook is also straightforward and easy:
ansible-playbook gatherinfolocal.yml
Which returns
Prompt for password
This second playbook we are going to abstract the info a bit by utilizing some variables in the playbook itself.
---
- name: Gather Datacenter Information from VMware using REST API
hosts: localhost
gather_facts: no
collections:
- vmware.vmware_rest
vars:
vcenter_hostname: 'vnoobcenter.rosalita.local'
vcenter_username: 'administrator@vsphere.local'
vars_prompt:
- name: vcenter_password
prompt: vCenter Password?
tasks:
- name: Get Datacenter information
vmware.vmware_rest.vcenter_datacenter_info:
vcenter_hostname: "{{ vcenter_hostname }}"
vcenter_username: "{{ vcenter_username }}"
vcenter_password: "{{ vcenter_password }}"
vcenter_validate_certs: no
register: datacenter_info
- name: Display datacenter information
debug:
var: datacenter_info
This playbook is virtually the same as the one before except now there are variables in use. vCenter_Hostname and vCenter_username are effectively the same except the are just in a slightly different location in the playbook. These variables are then used during the task.
Next is vars_prompt. This will prompt the user to enter the variable when the playbook is run. In this instance it will be asking for the vCenter password. This is more secure than the first playbook as now password is stored in the playbook.
Running this playbook is exactly the same as the first
ansible-playbook gatherinfo.yml
But now we are prompted for the password before the play executes:
Inventory and Ansible Vault
For the last example an inventory file and a variable file are created. The folder and file structure look something like
- vmware folder is arbitrary and where I am storing this work
- inv.yml and gatherinfo.yml are the inventory file and the playbook file respectively
- group_vars is the default location where variables for groups are stored
- vcenters.yml is the group we create in the inventory file
The inventory file:
vcenters:
hosts:
vnoobcenter.rosalita.lan:
vcenter_username: administrator@vsphere.local
“vcenters” is the Ansible host group for our vCenter, this also correlates to the name of the group variable file vcenters.yml in the file structure. The host is vnoobcenter.rosalita.lan and a variable named vcenter_username is also created.
The playbook file:
---
- name: Gather Datacenter Information from VMware using REST API
hosts: vcenters
gather_facts: no
collections:
- vmware.vmware_rest
tasks:
- name: Get Datacenter information
vmware.vmware_rest.vcenter_datacenter_info:
vcenter_hostname: "{{ inventory_hostname }}"
vcenter_username: "{{ vcenter_username }}"
vcenter_password: "{{ vcenter_passwords[inventory_hostname] }}"
vcenter_validate_certs: no
delegate_to: localhost
register: datacenter_info
- name: Display datacenter information
debug:
var: datacenter_info
This looks much like the earlier versions, with one main change. For vcenter_password, we are referencing a nested variable. Think of vcenter_passwords as the group of variables and inventory_hostname as which specific variable. Since each host will have a different inventory_hostname, this will allow us to define different passwords for each vCenter.
The nested structure comes together when looking at the variable file vcenters.yml:
vcenter_passwords:
vnoobcenter.rosalita.lan: MyPassword
This file is placed in the group_vars directory and when the playbook is run the variables are automatically loaded for the playbook to use.
Now we don’t want this variable to just be in plain text, so we need to use the ansible-vault command to encrypt it.
Once encrypted, the file looks like this:
When we run the playbook we specify the password we used to encrypt the variable file and Ansible will pull the passwords from the file for each of the hosts.
ansible-playbook gatherinfoadv.yml -i inv.yml --ask-vault-pass
Ignore the dependency warnings 🙂
With this setup the Ansible playbooks and inventory can be expanded to account for as many vCenters as you like with any tasks.