I have been meaning to write about this neat little feature that was added to the govc CLI late last year that allows you to easily deploy any OVF/OVA without the need of ovftool. You might ask, why not use ovftool? Well, if you just need to perform a very basic OVF/OVA deploy and prefer not to install anything on your desktop, this can be a nice alternative. govc is provided as a simple binary that is platform agnostic and supports Windows, Linux & Mac OS X. govc is built using govmomi which is also known as the vSphere SDK for Go and this also means you can consume this capablitity beyond just the CLI but also programmatically if you wish. Obviously, the CLI is the easiest method which I will demonstrate below.
Just to be clear, there is still a huge amount of value in using ovftool as it contains a large mount of functionality that is not found any where else. It is still the recommended tool for deploying OVF/OVA across all VMware based Hypervisors and is extensively used by other VMware's products for general OVF/OVA deployment.
Here are the steps on using govc to deploy an OVF/OVA:
Step 1 - Download the latest govc binary for your platform which can be found here. In this example, I will be running govc on my Mac OS X system and you can easily download it by running the following commands:
curl -L https://github.com/vmware/govmomi/releases/download/v0.5.0/govc_darwin_amd64.gz | gunzip -d > /usr/local/bin/govc
chmod +x /usr/local/bin/govc
Step 2 - To verify that govc is working, go ahead and run the following command to retrieve the version which should display v0.5.0:
govc version
Note: If you are new to govc and want a quick primer on how it works, please head over to this article here for more details.
Step 3 - Next, we need to setup a couple of GOVC environmental variables which will define the vSphere environment (ESXi or VC) you plan to deploy to. You also have the option to specify this in the command-line using the --help option for more details. In this example, I will just set them as environmental variables. Below is an example of my environment which is going to be deploying directly to an ESXi host, you will want to update these variables based on your environment.
export GOVC_INSECURE=1
export GOVC_URL=nuc.primp-industries.com
export GOVC_USERNAME=root
export GOVC_PASSWORD=vmware123
export GOVC_DATASTORE=vsanDatastore
export GOVC_NETWORK="VM Network"
export GOVC_RESOURCE_POOL='*/Resources'
Note: If you are new to govc and want a quick primer on how it works, please head over to this article here for more details.
Step 4 - To ensure that govc can properly communicate with your vSphere enviornment, you can run the following command which should return details about the system you are connected to:
govc about
Step 5 - To deploy an OVF/OVA, we first need to create a spec file by inspecting the actual OVF/OVA using the import.spec command which will output in a JSON format. To make it easier to read, we will format the output using python. To do so, run the following command (replace with the OVF/OVA you wish to deploy):
govc import.spec /Volumes/Storage/Images/Current/VMware-VCSA-all-6.0.0-3634788/vcsa/vmware-vcsa | python -m json.tool
As you can see from the screenshot above, we are inspecting the OVA for the latest vCenter Server Appliance (VCSA) 6.0 and it has automatically generated all the OVF properties that can be specified for this OVA. We then just need to re-direct the output to a file in which we can then edit the properties and pass that configuration when we deploy. We can do so by running the following command:
govc import.spec /Volumes/Storage/Images/Current/VMware-VCSA-all-6.0.0-3634788/vcsa/vmware-vcsa | python -m json.tool > vcsa.json
Step 6 - Now, we just need to open up the JSON file we saved and edit the values before we can use it in our deployment. You may have also noticed that there is an InjectOvfEnv param which means you can use govc to also inject OVF properties when deploying directly to ESXi host 🙂
Here is an example of the vcsa.json for deploying an Embedded VCSA:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"Deployment": "tiny", | |
"DiskProvisioning": "thin", | |
"IPAllocationPolicy": "dhcpPolicy", | |
"IPProtocol": "IPv4", | |
"InjectOvfEnv": true, | |
"Name": "VCSA-60u2-Embedded", | |
"PowerOn": true, | |
"PropertyMapping": [ | |
{ | |
"Key": "guestinfo.cis.appliance.net.addr.family", | |
"Value": "ipv4" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.mode", | |
"Value": "static" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.addr", | |
"Value": "192.168.1.40" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.prefix", | |
"Value": "24" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.gateway", | |
"Value": "192.168.1.1" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.dns.servers", | |
"Value": "192.168.1.1" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.net.pnid", | |
"Value": "192.168.1.40" | |
}, | |
{ | |
"Key": "guestinfo.cis.vmdir.password", | |
"Value": "VMware1!" | |
}, | |
{ | |
"Key": "guestinfo.cis.vmdir.domain-name", | |
"Value": "vghetto.local" | |
}, | |
{ | |
"Key": "guestinfo.cis.vmdir.site-name", | |
"Value": "virtuallyGhetto" | |
}, | |
{ | |
"Key": "guestinfo.cis.vmdir.first-instance", | |
"Value": "True" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.root.passwd", | |
"Value": "VMware1!" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.root.shell", | |
"Value": "False" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.ssh.enabled", | |
"Value": "False" | |
}, | |
{ | |
"Key": "guestinfo.cis.appliance.ntp.servers", | |
"Value": "pool.ntp.org" | |
}, | |
{ | |
"Key": "guestinfo.cis.deployment.node.type", | |
"Value": "embedded" | |
}, | |
{ | |
"Key": "guestinfo.cis.ceip_enabled", | |
"Value": "False" | |
} | |
], | |
"WaitForIP": false | |
} |
Note: There is a known bug currently in which the "Deployment" pararm is always generated. You will need to delete this if you have an OVA that does not use this parameter. I have already been reported here.
Step 7 - Finally, we just need to use the import.ova command and specify the path to our JSON configuration file as well as the path to our OVA. To do so, run the following command:
govc import.ova -options=vcsa.json /Volumes/Storage/Images/Current/VMware-VCSA-all-6.0.0-3634788/vcsa/vmware-vcsa
Note
Note: There is known bug in which you will see a warning about Invalid value for the network which you can ignore. I have already reported the issue here.
Once the VM powers on, the OVF properties will automatically be injected into the VM and in a few minutes, you will have a fully configured VM. Pretty cool right!? What I really love about this solution beyond its simplicity is that the tool allows you to easily generate the OVF property spec file. This is much easier than having to manually inspect an OVF/OVA and then extract the params by hand which can be very error prone. Lastly, I want to give a big shoutout to Pieter Noordhuis who was the Engineer who had implemented this awesome feature and is also one of the Engineers who created govmomi. Thanks Peter!
Axel says
Hello,
I would like to experiment with a VM distributed as an OVA with properties.
But... is the above supposed to work on ESXi with a free license?
This is what I get with govc (first the output of "about", followed by the error reported by "import.ova"):
Name: VMware ESXi
Vendor: VMware, Inc.
Version: 6.0.0
Build: 3620759
OS type: vmnix-x86
API type: HostAgent
API version: 6.0
Product ID: embeddedEsx
UUID:
./govc_darwin_amd64: Line 151: Unsupported element 'Property'
Trying through the web interface (EHC), vSphere Client and ofvtool raises the same kind of error message.
Many thanks in advance,
Axel
BaDcHaD says
govc import.spec /tmp/VMware-vCenter-Server-Appliance-6.5.0.5100-4602587_OVF10.ova
govc: failed to parse ovf: strconv.ParseUint: parsing "-100": invalid syntax
BaDcHaD says
Seems vmware bundled their own CLI installer into the ISO.
Mani says
I have an ova that is stored locally on a ESXi host.
From esxi shell I can see the full path of the file as - /vmfs/volumes/HDD01/ova/ubuntu.ova
My environment is set with the following value for datastore
export GOVC_DATASTORE=HDD01
I am able to see the ova file using
govc datastore.ls -l ova
or
govc datastore.ls -l /ova
However it is not clear to me, what path I need to provide for govc import.spec.
I tried
govc import.spec /ova/ubuntu.ova
govc import.spec ova/ubuntu.ova
Both return with "no such file or directory"
I'd appreciate any help on this.
Thank You.
Dayananda says
Hi william , Nice Article and very useful commands but I want to know whether a vm (vmname) exists in the given datacenter or not[I should validate only the vmname exist or not not its IP] . please provide me the link or script ASAP...
Thanks in advance
Jeff Creek says
InjectOvfEnv is not working for me on ESXi 6.5 and govc 0.15.0. Does this only work on vCenter not directly to ESXi?
Jaroslav says
Works great on version 6.0 but I'm unable to make govc work with vsphere version 6.5. I always end with unconfigured VM (localhost instead of IP) . Any ideas?
Jaroslav says
I was able to deploy it using govc but only "Stage 1". Is there any way how to import "Stage 2" there as well?
Reid says
Thank you for sharing this! Being able to script this process, and do so without needing a vCenter Server, is a huge plus. Worked great for me.