Deploying a VM from a Content Library OVF/OVA template

Following on from my series of posts on uploading OVA files to Content Library, and searching content library, the final step of all of this would be to deploy a VM using one of these templates

Inputs Required

The list of inputs that we need is as follows

NameTypeDescription
datastoreVC:DatastoreThe datastore to deploy to
endpointVAPI:VAPIEndpointThe VAPI endpoint to use
folderVC:VmFolderThe folder to deploy to
hostVC:HostSystemThe target host for deployment
hostnamestringName of the new VM
ovfLibraryItemIdstringid of the content library item
respoolVC:ResourcePoolResource pool to deploy to

Setup

Similar to previous steps, the first thing you need to do is make a connection to the VAPI endpoint
var client = endpoint.client();

Next, we need to create a model for the deployment target – where are we deploying the VM to? We use the deployment target object for this:
var deploymentTarget = new com_vmware_vcenter_ovf_library__item_deployment__target();
deploymentTarget.folder_id = folder.id;
deploymentTarget.host_id = host.id;
deploymentTarget.resource_pool_id = pool.id;

The final step before we deploy the VM is to create a resource pool deployment spec, this include the name, and the datastore to use:
var resourcePoolDeploymentSpec = new com_vmware_vcenter_ovf_library__item_resource__pool__deployment__spec();
resourcePoolDeploymentSpec.accept_all_EULA = true;
resourcePoolDeploymentSpec.name = hostname;
resourcePoolDeploymentSpec.default_datastore_id = datastore.id;

Quite why the datastore is in that one rather than the deployment target is a mystery to me. The only thing I can think of is that the deployment spec includes the storage provisioning profile.

Deploying the VM

To deploy the new VM, we use the com_vmware_vcenter_ovf_library__item call, and pass the ovfLibraryItemId, with the deployment target and deployment specs that we created above
var ovfSvc = new com_vmware_vcenter_ovf_library__item(client);
var result = ovfSvc.deploy(null, ovfLibraryItemId, deploymentTarget, resourcePoolDeploymentSpec);

Returning the vmObject

The deploy method above returns a structure that includes the id of the VM which we can use to find the vmObject, which is an output item of type VC:VirtualMachine
vmObject = VcPlugin.getAllVirtualMachines(null, "xpath:matches(id, '" + result.resource_id.id + "')")[0];
The search returns an array, so I’m using the [0] to strip the object out of the array – searching on an id, there can only be one VM with a particular id unless you’re using linked mode .
Finally we close the connection to the endpoint
client.close();

Full code listing

// Set the VAPI endpoint to the first endpoint returned

if (endpoint == null) {  
  throw "Unable to locate a VAPI endpoint";
}
var client = endpoint.client();  

// create a DeploymentTarget  
var deploymentTarget = new com_vmware_vcenter_ovf_library__item_deployment__target();

deploymentTarget.folder_id = folder.id;
deploymentTarget.host_id = host.id;
deploymentTarget.resource_pool_id = pool.id;

// create a ResourcePoolDeploymentSpec  
var resourcePoolDeploymentSpec = new com_vmware_vcenter_ovf_library__item_resource__pool__deployment__spec();
resourcePoolDeploymentSpec.accept_all_EULA = true;
resourcePoolDeploymentSpec.name = hostname;
resourcePoolDeploymentSpec.default_datastore_id = datastore.id;
  
// deploy the ovf  
var ovfSvc = new com_vmware_vcenter_ovf_library__item(client);
var result = ovfSvc.deploy(null, ovfLibraryItemId, deploymentTarget, resourcePoolDeploymentSpec); 

// return the vmObject
vmObject = VcPlugin.getAllVirtualMachines(null, "xpath:matches(id, '" + result.resource_id.id + "')")[0];
client.close();

19 thoughts on “Deploying a VM from a Content Library OVF/OVA template

  1. Hi Richard, I was wondering if you knew which global permissions needed to enable for content library so that I can deploy from it. I only need to deploy so I’ve set Content library > Download files and Content library > Read storage but I’m still getting permission errors. I can deploy from the VM template folder ok just not from the content library. I’m currently running vRO 7.4 (looking at moving up to 7.6). Thanks.

    • The main thing to be aware of with content library is that permissions for it are applied as global permissions, rather than from the vcenter object. I think with those applied as a global permission, plus the normal permissions for deploying a VM from template, it should work.

  2. Thanks Rich, That’s what I had hoped but I’m still getting permission errors so was wondering if there was anything else you had stumble on. I’ll keep looking (unfortunately the vsphere environments is managed by others so it takes a while getting them to make changes for testing).

    • Hi Rich,
      I hope you don’t mind one more question, have you seen a way to apply the guest customization to a vm? I’m assuming its com_vmware_vcenter_ovf_vcenter__guest__customization I need to apply somehow to the deployed vm.

    • They get configured at a later step in the flow, but it’s code that I’ve not written, so I’m a little reluctant to share someone else’s code.
      However the code we use is very similar to that in the “VcVirtualEthernetCardDistributedVirtualPortBackingInfo” action, so you could have a look at that

      • hi Rich, I added these lines to the code to set VLAN
        resourcePoolDeploymentSpec.network_mappings.key = att_networkInfo.key;
        //resourcePoolDeploymentSpec.network_mappings.value = att_networkInfo.value;
        I get the portgroup key using VcDistributedVirtualPortgroup, but when trying to deploy I get this error
        TypeError: Cannot set property “key” of null to “dvportgroup-624”

  3. Hi Rich, great post, i started testing, i can get the library items (all are ovf) and i picked one template ID and start deployment but it fails in vcenter with not much explanation: “failed to deploy ovf package”

      • thanks Rich, I was able to fix that and deploy a VM, now I am trying to pass portgroup info so that VM gets added to specific VLAN, I added these lines to the code to set VLAN
        var resourcePoolDeploymentSpec = new com_vmware_vcenter_ovf_library__item_resource__pool__deployment__spec();
        resourcePoolDeploymentSpec.accept_all_EULA = true;
        resourcePoolDeploymentSpec.name = att_vmName;
        resourcePoolDeploymentSpec.default_datastore_id = att_datastore.id;
        resourcePoolDeploymentSpec.network_mappings[0].key = att_networkInfo.key;
        resourcePoolDeploymentSpec.network_mappings[0].value = att_networkInfo.value;
        I get the portgroup key using VcDistributedVirtualPortgroup, but when trying to deploy I get this error
        TypeError: Cannot set property “key” of null to “dvportgroup-624”. I am not sure if I need to do some initialization or declaratiof of type initially for resourcePoolDeploymentSpec.network_mappings

      • I think instead of trying to assign values directly to resourcePoolDeploymentSpec.network_mappings[0].key for example, you need to create a map:
        eg
        $netmap = @{att_networkInfo.key = att_networkInfo.value}
        …and assign that to network mappings
        eg
        resourcePoolDeploymentSpec.network_mappings = @($netmap)

  4. Hi Jorge, difficult to help without seeing your environment, but I would probably start by adding logging entries to output all your variables so you can see if anything is empty or wrong there

  5. Hi Rich,
    I’m a newbie to VRO and was wondering the code posted here, would I run this as a scriptable task. Sorry for dumb question, also can you share any good resource on trying to learn VRO.

Leave a comment