This has been a topic I have been wanting to write about for quite some time, especially as I get asked about this on fairly regular basis from both partners and customers. I normally point folks over to our official Virtual Appliance (VA) authoring tool, VMware Studio which includes a number of development resources to help get started. Studio is used by many of our partners when creating their VA offerings, although it may not be the easiest thing to get started with, it does provide a complete end-to-end solution.
Most recently, I found myself building out a couple of VAs for my own day to day use, including a custom PhotonOS OVA that allows me to configure a static network address during deployment through the use of custom OVF properties. The official PhotonOS OVA that VMware ships does not provide this option and automatically defaults to DHCP. If you want to setup a static IP Address, you would need to first deploy the VM and then login to the console or SSH (if you have DHCP enabled) and then manually update the networking settings.
For my use case, Studio was going to be overkill and not to mention it may not even support PhotonOS or other modern OSes in general. However, everything that is needed to build your own VA is actually available right in vCenter Server. This was the perfect opportunity and excuse for me to finally document *my* process, in case it can help others wanting to do the same, especially for a home lab setup. In Part 1, I will take you through the two important concepts of building your own VA and then in Part 2 and Part 3, we will take a look at building both a Linux and Windows VA. I will also publish a reference Linux and Windows implementation so that you can use that as a basis to build your own VA, which is not limited to just Linux or Windows, it can be ANY GuestOS that vSphere supports.
OVF Properties
These are simply key/value pairs that are defined outside of the Virtual Machine and then specified during deployment by a user when importing an OVF/OVA. If you have ever deployed a VMware-based VA using the vSphere UI, you probably would have seen a wizard similar to the one above prompting for input whether that is networking, credentials, application settings or any other configuration for that matter. These key/values pairs by themselves have no meaning, you can literally have Key=Foo with Value=Bar. The real magic is how these key/values are then processed from within the GuestOS to actually do something interesting like customizing the network stack or initializing or configuring an application to start.
The way in which this happens is through the use of VMware Tools being installed within the GuestOS AND enabling the OVF environment transport mechanism for the given VM. Once this is done, we can then access these key/value pairs directly from the GuestOS for further processing.
GuestOS Customization Script
As alluded from the previous section, the the OVF key/value properties are accessed from within the GuestOS and this is done by the use of a startup script that would run automatically run when the VM is powered on. This guest script can be written using any language and its job is to take the key/value pairs and do something with them, such as reconfiguring a network interface as an example. This also means that the creation of the guest script and what it performs is completely up to the end user, this would be no different if you were to create an Automation script for the GuestOS to perform a specific task. This is an important fact as this is where users will be spending the majority of their time when developing their own VA, it is completely based on how simple or complex you would like to get with your customization and the code required to perform the operations from within the GuestOS.
Getting Started
Now that you have some background in how the OVF properties are defined and then consume within the GuestOS, let's now take a look at what you need to setup to start developing your own VA.
Step 1 - In vCenter Server, create a new VM with your desired configuration and then install an operating system of your choice. Install VMware Tools, apply all OS updates and then shutdown the VM before proceeding to the next step.
Step 2 - Select the VM in the Inventory and then click on Configure->vApp and then check the Enable vApp Options. Once enabled, select OVF environment for the IP allocation scheme as shown in the screenshot below.
Step 3 - In the OVF Details tab, select VMware Tools for the OVF environment transport
Step 4 - (Optionally) You can specify some additional metadata including appliance name and URLs to help others who maybe consuming your VA once it has been exported as an OVF/OVA.
Step 5 - Now we are ready to create some OVF properties, simply click on Add and provide a Label, Key and optional Category. For example, we can use Hostname as the label and then the Key will automatically assume the same name. You may want rename key to something easier to remember, especially if your label has spaces in it. I generally like to prefix everything with guestinfo. and then a unique id representing the field. In my example, I am using guestinfo.hostname and this is the key you will need to parse out from the startup script. For development and testing purposes, you can also set a test Value which will allow you to access the key and value while developing your script.
For this example, we will just create a single OVF property and then power on our VM once the change has completed.
Step 6 - Once the VM is powered on, go ahead and login to your OS. In my example, I am using PhotonOS, a Linux VM but the instructions will be simliar for other OSes.
Next, run the following command to access the OVF Environment which will include a number of properties including the OVF key/values that we had just defined.
vmtoolsd --cmd "info-get guestinfo.ovfEnv"
Note: In Windows, if you do not have VMware Tools in your PATH, you can run it using C:\Program Files\VMware\VMware OVF Tool\vmtoolsd.exe
Here is an example output for our specific OVF property:
The output is an XML format and you can find all OVF properties under the PropertySection. It is recommended that you store the output in either a variable or even a file which you can then use to parse out the specific keys and values. Hopefully it is clear now in how the OVF key/value pairs are defined at the VM level and then access directly from within the GuestOS. At this point, it is simply creating your customization script in whatever language you are familiar with and have it automatically run during the initial boot-up of the VM. You should also consider creating a specific file when the customization completes, this way you can check if the customization has ran before and will not automatically run again upon the next reboot. Another option is to simply disable or self-delete the script so that it does not run again, this may be challenging if you need to perform debugging but something to consider when you have completed your script.
Another quick way to view the OVF environment is using the vSphere UI. When the VM is powered on, you can click on the View OVF Environment button which will display the exact same output as if you were running it within the GuestOS. This could be useful for debugging or simply developing the script outside of the GuestOS.
In Part 2, we will take a look at a reference implementation for building a Linux VA which will include a sample OVF file and a sample script to help process our OVF properties. Stay tuned!
Additional OVF Resources:
- https://www.williamlam.com/2013/12/did-you-know-ovf-supports-cool-feature.html
- https://www.williamlam.com/2013/08/flexible-ovf-deployments-using.html
- https://www.williamlam.com/2013/12/deploy-truly-dynamic-ovf-using.html
Uwe Hale says
I've been wondering how you do your templates for the nested esxi hosts. I'd like to just provide a static ip, gw, hostname, etc. and have a new nested esxi vm. Please cover that in part 3 or 4 or ..... Thanks.
John says
How do you do this using just VMWare ESXi 6.7? There is no vApps and the vmtoolsd.exe always returns "No value found".
Could you please make a post specifically on how to do this with an OVF in ESXi 6.7?
Is there something to add to the .OVF file? Is there then some way to grab this information via vmtoolsd.exe? Thanks
William Lam says
Not sure if you're the same person asking what looks to be the exact question, if so, please don't spam in multiple places with the same question. Just ask it once.
Please see my reply at https://www.reddit.com/r/vmware/comments/anxmxt/how_do_i_set_an_ip_when_deploying_an_ovf_via/efxe6uw/
raduiacobescu says
Hi William,
Any idea if I can create a vApp using the ovftool, or at least overwrite one?
I want to create a script to deploy the VM (os v1.1, os v1.2) but I want to specify the same mac address/ip address in order to get the same ip address?
Basically reuse the vApp or specify the vApp environment properties with the ovftool so I can access it always on the same ip.
Thank you!
Elhanan says
you realize that vmware studio, is long dead and buried right? i'm trying to get away from it, and use packer, however i don't seem to have a way to inject vapps properties i nit