Ansible & VMware

Further to the post Ansible & Cisco ACI I wanted to add the next basic common task which is to create a virtual machine in vSphere using Ansible. This provides the fundemental knowledge to create network related configurations in Cisco ACI and to create VM’s in vSphere leading to a scripting a full deployment of a network and server infrastructure in Cisco ACI and VMware.

Leading on from the previous post, we now need to install some VMware scripts. We install ‘pysphere’ with pip.

# pip install pysphere

Thats it. We are now ready to create a playbook to create a virtual machine in vSphere. Create a new file in the playbook folder you created in the earlier post,  name the file ‘vm-from-template.yml’. We will create a VM from a VM template already setup in vSphere. I will post an example of creating a new VM using an ISO from the data store too.

For the playbook to create a VM from template, add the following to the ‘vm-from-template.yml’ file. You will need to adjust the relevent details to fit your environment.


- name: create intranet web vm
  hosts: vcenter
  connection: local
      
  vars:
    validate_certs: no
    vcenter_host:       '{{ inventory_hostname }}'
    esxi_host:          'vesx65.hugecompany.com'
    vcenter_datacenter: 'UK-THW'
    vcenter_datastore:  'NFS'
    vcenter_folder:     'Intranet Services'
    
    vms:
      - guest: 'Web010'
        vcpu_hotadd: 'no'
        mem_hotadd: 'no'
        notes: 'Ansible Created for Intranet Web'
        num_disks: 1
        osid: 'ubuntu64Guest'
    
  tasks:
    - name: create vms (Single Disk)      
      vsphere_guest:
        validate_certs: no
        guest: "{{ item['guest'] }}"
        from_template: 'yes'
        template_src: 'intranet-web-template'
        vcenter_hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_user }}"
        password: "{{ vcenter_pass }}"
        vm_extra_config:
          notes: "{{ item['notes']|default(omit) }}"
          folder: "{{ vcenter_folder }}"        
        vm_hardware:
          osid: "{{ item['osid'] }}"        
        esxi:
          datacenter: "{{ vcenter_datacenter }}"
          hostname: "{{ esxi_host }}"
      with_items: "{{ vms }}"

We use a template called ‘intranet-web-template’ to create the new VM in the DC. You will notice that the ‘hosts’ now refers to ‘vcenter’ where it was ‘apic’ in the Cisco ACI tasks. We need to modify the ansible hosts file to include the vCenter server. We create a new section called [vcenter] and a second section for the variables called [vcenter:vars]. The final hosts files looks like this, adjust the details to fit your environment.

[apic]
192.168.133.200

[vcenter]
192.168.210.30

[vcenter:vars]
ansible_connection = local
vcenter_user = administrator@vsphere.local
vcenter_pass = WMware12345

[apic:vars]
ansible_connection = local
aci_username = admin
aci_password = C1sco12345

Check we have comms with the vSphere server.

# ansible vcenter -m ping

We are ready to create a new VM from a template.

# ansible-playbook vm-from-template.yml

You should now have a new VM created from your given template in vCenter.

 

Creating a VM from ISO in Datastore Playbook

This playbook has vSphere create a new VM using an ISO in the data store. This ISO is for a Windows 8 build.

- name: create some vms
  hosts: vcenter
  connection: local

  vars:
    validate_certs: no
    vcenter_host:       '{{ inventory_hostname }}'
    esxi_host:          'vesx65.hugecompany.com'
    vcenter_datacenter: 'UK-THW'
    vcenter_datastore:  'NFS'
    vcenter_folder:     'Intranet Services'

    vms:
      - guest: 'win8-iso'      
        state: 'powered_on'
        vcpu_hotadd: 'no'
        mem_hotadd: 'no'
        notes: 'Ansible Created'
        num_disks: 1
        disks:
          disk1:
            size: 10
            type: 'thin'
        network: 'hugec|app1a|weba_epg'
        memory: 1024
        cpus: 1
        osid: 'ubuntu64Guest'


  tasks:
    - name: create vms (Single Disk)

      vsphere_guest:
        validate_certs: no
        guest: "{{ item['guest'] }}"
        state: "{{ item['state'] }}"
        vcenter_hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_user }}"
        password: "{{ vcenter_pass }}"

        vm_extra_config:
          vcpu.hotadd: "{{ item['vcpu_hotadd']|default(omit) }}"
          mem.hotadd: "{{ item['mem_hotadd']|default(omit) }}"
          notes: "{{ item['notes']|default(omit) }}"
          folder: "{{ vcenter_folder }}"

        vm_disk:
          disk1:
            size_gb: "{{ item['disks']['disk1']['size'] }}"
            type: "{{ item['disks']['disk1']['type'] }}"
            datastore: "{{ vcenter_datastore }}"
            folder: "{{ vcenter_folder }}"

        vm_nic:
          nic1:
            type: "vmxnet3"
            network: "{{ item['network'] }}"
            network_type: dvs
        
        vm_hardware: 
          memory_mb: "{{ item['memory'] }}"
          num_cpus: "{{ item['cpus'] }}"
          osid: "{{ item['osid'] }}"
          scsi: "paravirtual"
          vm_cdrom:
            type: 'iso'
            iso_path: 'NFS/ISO/en_windows_8_enterprise_x86_dvd_917587.iso'

        esxi:
          datacenter: "{{ vcenter_datacenter }}"
          hostname: "{{ esxi_host }}"

      with_items: "{{ vms }}"

Again to run this;

# ansible-playbook vm-with-datastore-iso.yml