Automate VMware vSphere 7 with Ansible and save lifetime

Automate your VM and VMare vSphere environment with Ansible and provision virtual machine s automatically.Want to know how to provision your virtual machines for your environment automatically? It’s actually pretty simple and I think after a few tries it will hopefully work for you and get you moving forward. The following article is valid for all VMware vSphere versions since 6.x also for vSphere 7. I think it´s also working on 5.5 and newer, but I haven´t tested it.

I have now already written a few articles about Ansible and also Packer and published them here on the blog. With Packer you can easily create templates for your VMs and the whole thing also about continuous deployment and continuous integration (CD/CI). The main goal of this blog series is to provide a completely automated LAB environment. So including Active Directory, Memberserver, Fileserver etc… But today we start with VMs on VMware vSphere.

Normally the setup of a new environment with multiple VMs is a lot of work, even if you can already use many advantages of VMware vSphere, templates, cloning, guest customization and so on. But it still takes some time and especially if you try a lot of software tests or configs, like I do, it is always quite time consuming to rebuild the lab.

To save you a little work I have already created an Ansible Role for this. The advantage is that you have a compact playbook that you can extend as you like. I will limit this article to Windows VMs for now, if you want to have Linux VMs, you can simply modify the role or copy it and create your own. So let’s get started 😉

What is important to have a working VM on vsphere?

What do we need to provide a working VM? First of all, there is a virtual machine, i.e. the shell. Then CPU, RAM, HDD, LAN and of course the image or template for the operating system that will later run inside the virtual machine.

In the previous article I already explained how you can create the image or template with Packer. You can use the instructions to provide all current Windows versions as a template. So in this article I will talk more about how you can deploy the VMs.

Build the foundation

Basic Setup Ansible

If you have alredy installed Ansible, you can go over this step.

Before we can start, we first need to install Ansible. I chose Ansible for a very simple reason. I find it relatively easy to quickly deploy different LAB environments for this purpose. Of course you can also use Terraform. But since the required modules are also available for Ansible, I decided to go this way. In my opinion, there is no right or wrong in DevOps. I think you should use the technologies that are available as good as possible for you and with that create as little effort as possible.

How to install and set up Ansible you can read in the following article again for Windows Subsystem for Linux

or for a dedicated machine with Ubuntu.

The VMware vSphere Ansible Module

To be able to deploy our VMs on VMware vSphere, we first have to make sure that Ansible gets the necessary Pyhton modules to do this for us. For this we install the WinRM module, which we will need later anyway, and also the module for VMware vSphere. Ansible can then access these Pyhton modules and execute the actions with them.

sudo pip3 install pywinrm
sudo pip3 install pyvmomi

Deploying my VMs on VMware with Ansible

Below I will go into a little more detail about the playbook and my definition files that I use for automated deployment of VM s on VMWare Vspere 7. You can download the entire playbook with roles and variables from my Github repository, modify it and get started right away.

Structure of my Ansible inventory

As already mentioned above, I want to build as flexible as possible many different LAB setups, for this I don’t use host variables, I don’t need them for this. I have already stored the settings in my inventory. I can take at any time further parameters by Varialbe from the role and give these directly in the Inventory.

Of course you can also manage the whole thing via host variables. For me it was as already said easier to edit a file with search and replace, than several files and orders.

#define childgroups for homelab
[homelab:children]
VMs
# VMs to create
[VMs]
192.168.1.40 guest_hostname='dc01' guest_vcpu='2' guest_vram='4096'
192.168.1.41 guest_hostname='ctxcc01' guest_vcpu='2' guest_vram='4096'
192.168.1.42 guest_hostname='ctxts01' guest_vcpu='2' guest_vram='4096'

Structure of my Ansible group vars

In my case I want to have all of my central variables in one place. I can copy it quickly and can create multiple environments in a short time. Take a look. I Think most of this is that is easy to understand.

#local Serverlogin for Windows VMs
ansible_user: Administrator
ansible_password: YourPassw0rd
ansible_port: 5986
ansible_connection: winrm
ansible_winrm_server_cert_validation: ignore
#VMware Settings
vcenter_datacenter: "DatacenterName"
vcenter_cluster: YourCluster
vcenter_hostname: vcenter.lab.local
vcenter_user: administrator@vsphere.local
vcenter_pass: YourPassw0rd
validate_certs: false
vmtemplate: Template-Base2019_1608578927
datastore: ds_vmlab
vm_foldername: /LAB
vm_network: vnetVMs
#Virtual Maschine Settings
#Variablen spezifisch für Umgebung
guest_netmask: '255.255.255.0'
guest_gateway: '192.168.1.1'
#IP of your Domaincontroller
guest_dns_server1: '192.168.1.40'

Secure your variable File with your Passwords

Normaly you should save the variables containing your Passwords in a Vault. You can do this with the following command:

ansible-vault encrypt FILENAME

You get will get promted to enter your password twice.

If you want to unencrypt your variable file you can use:

ansible-vault decrypt FILENAME

The problem is, you have to decrypt the file before using it.

Another way to secure your variable files is shown on the following site:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#best-practices-for-variables-and-vaults

Structure of my vSphere Ansible role

Of course, for the playbook of your environment, you can also manage everything within a playbook. I prefer to do this with a role. Because then I simply have a clear playbook and it is easier for me to copy or change. It also allows me to create as many VMs as I want with little effort.
Here you can have a closer look at the role. Basically all important information is defined here. Connection to vCenter, Datacenter, Cluster etc. Also the most important settings for the virtual machines.

This role first creates the VM in vSphere with the defined template. After that, I directly perform all the first required customizations of the VM. In this step I already store the IP address, subnet, DNS, etc. Also the Windows DNS name. After that I wait for a while and check the result again.

# Created by Thomas Preischl 06/2020
---
- name: Create VM from template
  vmware_guest:
      validate_certs: False
      hostname: "{{ vcenter_hostname }}"
      username: "{{ vcenter_user }}"
      password: "{{ vcenter_pass }}"
      cluster: "{{ vcenter_cluster }}"
      datacenter: "{{ vcenter_datacenter }}"
      name: '{{ guest_hostname }}'
      folder: "{{ vm_foldername }}"
      template: "{{ vmtemplate }}"
      datastore: "{{ datastore }}"
      # disk:
      #   - size_gb: "{{ disk_size | default(50) }}"
      #     type: thin
      #     datastore: "{{ datastore }}"
      networks:
      - name: "{{ vm_network }}"
        ip: '{{ inventory_hostname }}'
        netmask: '{{ guest_netmask }}'
        gateway: '{{ guest_gateway }}'
        dns_servers:
        - '{{ guest_dns_server1 }}'
      # - '{{ guest_dns_server2 }}'
      hardware:
        num_cpus: '{{ guest_vcpu }}'
        memory_mb: '{{ guest_vram }}'
      customization:
        hostname: '{{ guest_hostname }}'
        password: '{{ ansible_password }}'
        joinworkgroup: 'workgroup'
        timezone: 110
      wait_for_customization: True
      state: poweredon
  delegate_to: localhost
  register: newvm
- name: Wait until connection to vm
  wait_for_connection:
    delay: 5
    timeout: 900
- name: Gather facts for the first time
  setup:

Running the Playbook – Deploy VMs on vSphere

Now after a big part of theory and explanation, we want to run the playbook. You can start it with:
ansible-playbook -i /pathToInventory /PathToPlaybook.

Ansible Role for VMware Sphere - The playbook running

You will see the VMs will be deployed from the templates. It will take a view munites depending on your storage and system resources.

VMs are created with vmware ansible role

If everythin is fine, you will see it in your playbook. If you have problems or something is failed you can append the parameter “–debug” on you commandline to get more details in the output of you Playbook.

Check also my other article about Ansible, Automation and VMware or Citrix.

Or take a look how to depoy the Active Directory in the next step.

5 thoughts on “Automate VMware vSphere 7 with Ansible and save lifetime”

  1. Hello Thomas,

    My inventory file is not picking these parameters “guest_hostname, guest_vcpu, guest_vram, guest_custom_ip”

    when I run the playbook I got below error msg.. variable is not defined for guest_hostname.. my playbook and inventory file looks fine..

    fatal: [localhost]: FAILED! => {
    “msg”: “The task includes an option with an undefined variable. The error was: ‘guest_hostname’ is undefined\n\nThe error appears to be in ‘/opt/myagent/avi/ansible/main.yaml’: line 21, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n

    my inventory file like this

    [vms]
    guest_hostname=’test-deploy1′ guest_vcpu=’1′ guest_vram=’2096′ guest_custom_ip=’0.0.0.0′
    guest_hostname=’test-deploy2′ guest_vcpu=’2′ guest_vram=’4096′ guest_custom_ip=’0.0.0.0′

    I ran playbook like these
    ansible-playbook -i (path of inventory file) (playbook path) -vvv

    Kindly help what was I missed here..

  2. Great stuff:

    I am getting this error:
    Am I missing something on the ansible side?

    ERROR! ‘vmware_guest’ is not a valid attribute for a Play

    The error appears to be in ‘/home/uadmin/ansible-playbooks/vmdeploy/deploy_vms.yaml’: line 2, column 3, but may
    be elsewhere in the file depending on the exact syntax problem.

    The offending line appears to be:


    – name: Create VM from template
    ^ here

Leave a Comment

Your email address will not be published. Required fields are marked *