More often than not, we meet clients with hybrid environments. Most combinations we encountered were:
– VMware + AWS/Digital Ocean
– HyperV + Azure
– KVM + Digital Ocean

We’ll not be going into details regarding financial, legal or anything reason for having a hybrid environment. Below we’ll demonstrate deploying an on-premises virtual machine in a VMware environment.

Two main requirements for this to work are:
pyvmomi installed on Ansible control machine (simplified – pyvmomi is a python SDK that talks to VMware vSphere API)
– VMware environment (Vcenter, ESXi host)
– A VM template (we’ll be using a pre-configured CentOS7 template)

Below are the steps required to set up the environment and creating a new

1. Set up access credentials in VMware vCenter
In order for Ansible to be able to connect and modify our VMware environment a user needs to be creating in our vCenter server. For this demo we’ll create a new user ansible@vsphere.local which will have Administrator privileges.

2. Installing pyvmomi on Ansible Control machine
Installing pyvmomi on our ansible control machine is as simple as it gets. (we are using a CentOS7 machine as control machine):

# pip install pyvmomi
Collecting pyvmomi
Using cached https://files.pythonhosted.org/packages/eb/87/ebf153a3aafdac7c54c5578b6240d7930a8c0a1a21bdd98d271fd131673c/pyvmomi-6.7.3.tar.gz
Collecting requests>=2.3.0 (from pyvmomi)
Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): six>=1.7.3 in /usr/lib/python2.7/site-packages (from pyvmomi)
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.3.0->pyvmomi)
Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting idna<2.9,>=2.5 (from requests>=2.3.0->pyvmomi)
Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests>=2.3.0->pyvmomi)
Using cached https://files.pythonhosted.org/packages/e8/74/6e4f91745020f967d09332bb2b8b9b10090957334692eb88ea4afe91b77f/urllib3-1.25.8-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.3.0->pyvmomi)
Using cached https://files.pythonhosted.org/packages/b9/63/df50cac98ea0d5b006c55a399c3bf1db9da7b5a24de7890bc9cfd5dd9e99/certifi-2019.11.28-py2.py3-none-any.whl
Installing collected packages: chardet, idna, urllib3, certifi, requests, pyvmomi
Found existing installation: chardet 2.2.1
Uninstalling chardet-2.2.1:
Successfully uninstalled chardet-2.2.1
Found existing installation: idna 2.4
Uninstalling idna-2.4:
Successfully uninstalled idna-2.4
Running setup.py install for pyvmomi ... done
Successfully installed certifi-2019.11.28 chardet-3.0.4 idna-2.8 pyvmomi-6.7.3 requests-2.22.0 urllib3-1.25.8

3. Preparing the playbook
For the sake of simplicity we’ll use clear text credentials in this demo (in production env this is not recommended).
Many additional variables need to be added to the yaml file. Variable names are pretty straightforward, make sure the template_name variable is an exact name of VM template within VCenter.

After the VM is deployed to VMware, the playbook also adds VM hosts entry to our Ansible control machine:
– /etc/hosts
– /etc/ansible/hosts

The playbook:

- name: deploy VM on vmware
hosts: localhost
gather_facts: no
vars:
vcenter_host: 'vcenter.test.local'
vcenter_user: 'ansible@vsphere.local'
vcenter_pass: 'Demopass!'
esxi_host: 'esxi1.test.local'
vcenter_datastore: 'DEMO-ISCSI-R5'
datacenter_name: 'Datacenter'
cluster_name: 'Prod'
folder_name: 'Prod'
template_name: 'CentOS7-1'

vmname: demovm
hostname: demovm.test.local
network_label: 'Internal LAN'
ipaddr: 192.168.56.101
netmask: 255.255.255.0
gateway: 192.168.56.101
dns1: 1.1.1.1
dns2: 8.8.8.8

tasks:
- name: Creating the VM
vmware_guest:
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
validate_certs: False
name: "{{ vmname }}"
folder: "{{ folder_name }}"
template: "{{ template_name }}"
datacenter: "{{ datacenter_name }}"
state: poweredon
cluster: "{{ cluster_name }}"
disk:
- size_gb: 16
type: thick
autoselect_datastore: yes
networks:
- name: "{{ network_label}}"
ip: "{{ ipaddr }}"
netmask: "{{ netmask }}"
gateway: "{{ gateway }}"
start_connected: true
customization:
dns_servers:
- "{{ dns1 }}"
- "{{ dns2 }}"

- lineinfile:
path: /etc/hosts
line: '{{ ipaddr }} {{ hostname }}'

- lineinfile:
path: /etc/ansible/hosts
line: '{{ hostname }}'
4. Running the playbook
# ansible-playbook createvmwarevm.yml

PLAY [deploy VM on vmware] *************************************************************************************************************************************

TASK [Creating the VM] *****************************************************************************************************************************************
changed: [localhost]

TASK [lineinfile] **********************************************************************************************************************************************
changed: [localhost]

TASK [lineinfile] **********************************************************************************************************************************************
changed: [localhost]

PLAY RECAP *****************************************************************************************************************************************************
localhost : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

5. Access test
– first lets copy our SSH keys to the newly created VM for future access

# ssh-copy-id demovm.test.local
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: “/root/.ssh/id_rsa.pub”
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed — if you are prompted now it is to install the new keys
root@demovm.test.local’s password:
Number of key(s) added: 1
Now try logging into the machine, with: “ssh ‘demovm.test.local'”
and check to make sure that only the key(s) you wanted were added.

– test SSH access
# ssh demovm.test.local
[root@demovm ~]# hostname
demovm

We’re done! The VM was successfuly deployed on our vmware environment.