Create a new virtual machine in Vsphere with Python, Pysphere and the VMWare API

The VMWare API is very extensive and allows you to do almost all operations that are possible with VMWare using API calls. In order to be able to easily create and deploy new virtual machines, it can be a good idea to standardize and create VM’s using a (Python) script that calls the API. In this post, I will give some examples on how to easily create a new VM using Pysphere and the VMWare API.

In order to create a new VM on a fast and standardized way, I figured it would be a good idea to create a script that calls the VMWare API and executes the actions that I normally do manually via the GUI. For example to enable hot add cpu and memory. The script uses pysphere, documentation can be found here: https://code.google.com/p/pysphere/ and the VMWare API, documentation can be found here: http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html

Preparation to run the script

In order to use pysphere, we need to install the Pysphere library. The easiest way is to do this with PIP:

In order to simplify my scripts that were using Pysphere, I created a file that can be included into other scripts. The file contains function definitions related to Pysphere. Create a file vm_include.py and copy the following contents to the file or download it here: http://jensd.be/download/vm_include.py

Test the connection to Vsphere

Now we can start with a basic Pysphere example that will try to connect to a Vsphere cluster and list the type of connection.

Create host-info.py with the following contents:

Edit the host, user and password on line 6, 7 and 8 to match your installation.

The above script should return the type of the host (ESX or Vsphere) and the names of the VM’s that are running on it:

Create a new VM

The next step is to create a script that will actually add a VM to this host. To do so, copy and edit the contents of the following example to create-vm.py:

Edit the host, user and password on line 7, 8 and 9 to match your installation.

When executing the script, the new VM should be created as we defined and after creating, it should be started.

When looking at the inventory in the vSphere client, we can see that these action were performed as we expected:

As you can see, it’s very easy to get started to create VM’s from a script language like Python. This example on itself isn’t very ground-breaking, it’s what you do in combination with the script that matters.

For example, in order to create multiple new VM’s, I combine the above with a script that takes a YAML file as input. The input contains a list of specifications for the new machines. When executed, the script creates the VM’s, creates an entry in DNS for them, generates a root password and stores it in our password manager, gets the MAC of the newly created VM and PXE-boots the new VM with a kickstart file. As a result, it’s possible to deploy 100’s of VM’s including OS-installation and DNS-entry in minutes without any further action and even more important, without mistakes :)

More information about the scripts can be found on GitHub: https://github.com/jensdepuydt/python-hypervisor-api

34 thoughts on “Create a new virtual machine in Vsphere with Python, Pysphere and the VMWare API

  1. Hi Jens,
    Thanks for the script for creating vm using Pysphere API. It helped a lot.

    Since I am a newbie to Python & Pysphere API, I need help from you.
    I want to achieve build automation same way as you have mentioned in this post “Create a new virtual machine in Vsphere with Python, Pysphere and the VMWare API” (http://jensd.be/?p=370).

    I want combine the above script with a script that takes a YAML file as input. The input contains a list of specifications for the new machines. When executed, the script creates the VM’s, gets the MAC of the newly created VM and PXE-boots the new VM with a kickstart file.

    Can you provide me detailed steps to achieve this ?
    Thanks in advance.
    Parimal

  2. esx_host=”127.0.0.1″ … it says it cannot find it
    I’m guessing the esx_host is the machine on which I’m building the VM on?
    I also tried setting to the same IP that I’m connecting to.
    Thanks.

    • The esx_host is a specific host in the vSphere cluster.
      If you have a cluster that has 3 hosts, you need to determine on which of those 3 the VM needs to be deployed. it can be a name or IP.

  3. Thank you for this. I think you have a typo in the vm_include.py script:

    def createGuest(host_con,guest_dc,guest_host,guest_name,guest_ver,guest_mem,guest_cpu,guest_iso,guest_os,guest_disk_gb,guest_ds,guest_networkg,guest_enterbios):
    #get dc MOR from list

    The error doesn’t exist in the code on this page, but does exist in the code in this link here – http://jensd.be/download/vm_include.py

    typo is guest_networkg

    *You receive errors in the VM creation script regarding that variable not being globally defined.

  4. Hi Jens,
    I try to change the format of the disk to by replacing the line disk_backing=VI.ns0.VirtualDiskFlatVer2BackingInfo_Def(“disk_backing”).pyclass() by
    disk_backing=VI.ns0.VirtualDiskSparseVer2BackingInfo_Def(“disk_backing”).pyclass()

    But I have the error: Result: Cannot create guest: The device or operation specified at index ‘2’ is not supported for the existing virtual machine platform.

    Do you have any suggestion ?
    Thanks in advance
    Roch

    • Hi Jens,
      I found my error.
      To enable a disk with a thin provisionning type, I’ve just need to set the thinProvisioned( property, not to change to a VirtualDiskSparseVer2BackingInfo_Def disk that I think is used by VMware workstation.

      So, it works perfectly with
      disk_backing=VI.ns0.VirtualDiskFlatVer2BackingInfo_Def(“disk_backing”).pyclass()
      disk_backing.set_element_thinProvisioned(“True”)

  5. Hi,

    How can installation of OS on the newly created VM be handled through Python?

    Thanks,
    Prajakta

    • Hi,

      What I did at the time in my Python script was the following:
      – Create the VM using the scripts in this post
      – Once the VM is created, fetch back the MAC-address of the virtual NIC
      – Generate a root password
      – Generate a kickstart file (fill in some values in a template)
      – Generate a PXE-boot file supplying the kickstart file and name it with the MAC-address
      – Start the VM and let it PXE-boot (default in ESX)

      The VM will fetch the PXE-boot file and start the installation using the parameters supplied in the kickstart. Once installed, the boot order will prevent the VM to boot from PXE (you could also delete it afterwards).

      For the rest of the deployment you can continue with your favourite CM-tool (Ansible/Puppet/Chef/…)

    • you have to put hostname as ESXI hostname or IP address.
      Keep in mind datacenter name should be “ha-datacenter” like below:
      #!/usr/bin/python
      import vm_include

      def main():
      #connection properties
      #change these to match your installation
      host=”yourvspherehost”
      host_user=”root”
      host_pw=”vmware”

      #properties of the new VM:
      guest_name=”newvm” #name of the VM
      guest_mem=1024 #memory in MB
      guest_cpu=1 #number of virtual CPU
      guest_space=2 #space in GB
      datastore=”non-ssd” #name of the datastore
      esx_host=”10.0.0.1″ #specific host in the cluster
      guest_dc=”ha-datacenter” #datacenter name
      guest_ver=”vmx-08″ #version of VMX (v8 is editable via the client)
      guest_iso=”” #iso to mount (from datastore)
      guest_os=”rhel6Guest” #guest-template
      guest_network=”VM Network” #network-name
      guest_enterbios=False

      #connect to the host
      host_con=vm_include.connectToHost(host,host_user,host_pw)

      #create the new VM
      res=vm_include.createGuest(host_con,guest_dc,esx_host,guest_name,guest_ver,guest_mem,guest_cpu,guest_iso,guest_os,guest_space,datastore,guest_network,guest_enterbios)
      print “Result:”,res

      #start the new VM
      vm_include.powerOnGuest(host_con,guest_name)

      #disconnect from host
      host_con.disconnect()

      if __name__ == ‘__main__’:
      main()

  6. I am trying to understand about vm_include.py where does this needs to be defined at since it is already created and or what do I need to modify to be able to call this

    • Hi,

      It just needs to be there. It’s called from the other scripts by “import vm_include”. No need to modify it.

    • I’m sorry but I think your question is quite unrelated to the contents of the post. You can get all info on VM’s using the VMWare API in a similar way as described here.

  7. I want to create vm without the vcente. what should i do? I use your guest_ds but isn’t successful.

    • Sorry, haven’t tested the script without vCenter. I would need to take some time to have a look at this.

    • Hi, either you forgot to import the correct libraries or pySphere isn’t installed. This is where you should have a look at.

  8. hi
    i install your scripts but i have problem
    i change host to *.*
    but the error display
    //////////////////////////////////////////////////////
    Cannot find host: 10.0.0.1
    /////////////////////////////////////////////////////
    Please help me
    Tnx

    • You will need to change the script to reflect to your environment. 10.0.0.1 is in the example, the name/IP of a specific host in the cluster. Please adjust to what is valid for your host/cluster.

  9. Hi,I try it,but the error says:
    build vm’s result:Cannot create guest: The operation is not supported on the object.

    I don’t know why,I use the vcenter 5.1,maybe the version cause the error?

  10. Hello,
    I am getting below error while executing vm_create.py

    vm=host_con.get_vm_by_name(guest_name)
    File “build/bdist.linux-x86_64/egg/pysphere/vi_server.py”, line 304, in get_vm_by_name
    pysphere.resources.vi_exception.VIException: [Not Connected]: Must call ‘connect’ before invoking this method

    Please help me to resolve this error.

    Thanks,
    Shikha

  11. I am getting following error ->
    Note that My Host IP and esx_host ip’s are same because on esx_host only I want to create new vm.
    Error —->
    Result: Cannot find host: 172.16.213.222
    Traceback (most recent call last):
    File “./create-vm.py”, line 39, in
    main()
    File “./create-vm.py”, line 33, in main
    vm_include.powerOnGuest(host_con,guest_name)
    File “/root/training/python_training/my_practice/net/vm_include.py”, line 213, in powerOnGuest
    vm=host_con.get_vm_by_name(guest_name)
    File “/usr/lib/python2.7/site-packages/pysphere/vi_server.py”, line 304, in get_vm_by_name
    FaultTypes.NOT_CONNECTED)
    pysphere.resources.vi_exception.VIException: [Not Connected]: Must call ‘connect’ before invoking this method

    • My esx host 172.16.213.222 is reachable.

      [root@rhel7server net]# ./host-info.py
      Type: VMware ESXi

Leave a Reply

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