ccnasaurabh1
Enthusiast
Enthusiast

Details of vRA vSphere VM placement logic

we are looking for a way to allow Private Cloud (VRA) requestors to specify an individual ESX host to which a VM should be provisioned.  To accomplish this, we need a better understanding of how the vRA placement logic works with vSphere so that we can manipulate it to select a specific host within a cluster when choosing where the VM should land.

Are you aware of any documentation that goes in detail regarding the algorithm(s) used during vRA VM placement to a vSphere cluster?  Or are there any engineering/product team contacts within VMware that would be able to provide that information?

We *think* that we may be able to accomplish this using the method described in the following article, but even the author seems to make some assumptions when it comes to how the placement works out-of-the-box: https://vmguru.com/2017/07/how-to-specify-a-deployment-target-when-using-vrealize-automation/

Also, DRS is set to “Manual” for the ESX clusters where we would want to provision the VMs, so that should be taken into account as well for any VMware resources that may be answering these questions.

0 Kudos
12 Replies
daphnissov
Immortal
Immortal

we are looking for a way to allow Private Cloud (VRA) requestors to specify an individual ESX host to which a VM should be provisioned.

Why are you wanting to do this? What's the use case here?

0 Kudos
ccnasaurabh1
Enthusiast
Enthusiast

Because We have some  very critical VMs with 500GB + RAM and we made a ESXi host for specific VMs because of their critically. 

0 Kudos
daphnissov
Immortal
Immortal

Then in that case the better option is to pool hosts that can satisfy those workloads into a dedicated cluster, which then becomes trivial to target within vRA. Having lopsided clusters like what you have makes logic much more difficult as you're now finding out. vRA, I don't believe, has any host placement logic; it simply hands off the VM to vCenter and it registers it on the appropriate host. I'm not even sure if integration with vROps will help you out there. Long story short: Use dedicated clusters for extra-large VMs.

0 Kudos
ccnasaurabh1
Enthusiast
Enthusiast

But how to fix the Cluster or host name before VM provisioning ?

0 Kudos
daphnissov
Immortal
Immortal

You'll have to explain what you're asking about. If you provision a separate vSphere cluster for your large-sized workloads, you can consume that via a variety of ways in vRA. You'll have to obviously have a reservation (assuming we're talking about vRA 7.x here) and can then using automation to target that cluster dynamically.

0 Kudos
ccnasaurabh1
Enthusiast
Enthusiast

But requirement is not here for dynamic HOST or CLUSTER. Requirement is here, We required a static HOST where VM is going to be provision and that HOST name must be specified before provisioning.

Current VM provisioning Flow using VRA reservation and Recourse pool required a manual intervention to register a VM in specific HOST.

0 Kudos
daphnissov
Immortal
Immortal

As I said, you're not going to get a specific host as a destination. You need to pool those hosts into a cluster. Alternatively, you have separate clusters each of one host which is problematic for other reasons. vRA then targets the cluster.

0 Kudos
haloOne
Contributor
Contributor

You can provision to a ESXi host in vRA using these custom properties:

VirtualMachine.Admin.ForceHost

VirtualMachine.Admin.HostSelectionPolicy: EXACT_MATCH

0 Kudos
ccnasaurabh1
Enthusiast
Enthusiast

I do not want to provision a Host using VRA.

I need to provision a Vm in a specific ESXI Host using VRA.

0 Kudos
haloOne
Contributor
Contributor

Right, that property is not for provisioning a host its for placing a vm on a host.

take a look a vRA custom property reference guide

0 Kudos
ccnasaurabh1
Enthusiast
Enthusiast

Thanks Mate !

Allow me some Time to check it. I will keep you posted.

0 Kudos
GeiAll
Enthusiast
Enthusiast

Hi ccnasaurabh1.


We had the same issue you are spesiying here, and we have solved it in a simlar matter,
Using the event broker to trigger to turn of DRS for a VM, after deployment.

vRA is rather dump when it comes to placement of VMs during deployment (Hint: Metro clusters) and also we are using guest operations during provisioning and if DRS moves a VM during provisioning this will fail. So we turn off the DRS during deployment, and set it to default after deployment.

Also, setting DRS to manual is not correct. The VM might still change ESX host during reboot(it will however not move it while running). See the code below and take notice of:
drsVmConfigSpec.info.enabled = false;        
Setting it to false, means DRS is disabled, NOT manual.


(You also need the Custom properties as explained allready in this thread:
VirtualMachine.Admin.ForceHost
VirtualMachine.Admin.HostSelectionPolicy: EXACT_MATCH
)

If you want to make your solution a litte bit more "secure". I can metion that we use Tags in vCenter/vm/StoragePods/ESX etc. And rules in the vCenter to enforce them. So when a VM is deployed in vRA the Tags will be assigned to the VM. The VM will then always run on the host/cluster/datastore we want. (EG: a user deploys to a Metro Cluster and Storage+Cluster will always be on the same site.)
 


Anyway, we use 2 events in Eventbroker like this:


1. Eventbroker event Machine provisioning/Event/CloneWorkflow.CloneMachine.EVENT.OnCloneMachineComplete
(Should be blockable!)

This must turn off DRS.

2. Eventbroker event Macine provisioning/Post/VMPSMasterWorkflow32.BuildingMachine

Set DRS to "default"


The actual code is like this: (you need to add the logic around finding the VM)


function VerifyDRSEnabled(ClusterName)
{
    var T = ClusterName.configurationEx;

    var x = T.drsConfig;

    if (x.enabled == true && x.enableVmBehaviorOverrides == true)
    {
        return true;
    }
    else
    {
        System.log (ClusterName.Name+" does not have DRS enabled (or allow overide per vm.");
        return false;
    }

}

function SetVMToManual(VM)
{
    var drsVmConfigSpec = new VcClusterDrsVmConfigSpec();
    drsVmConfigSpec.operation = VcArrayUpdateOperation.add;
    drsVmConfigSpec.info = new VcClusterDrsVmConfigInfo();
    drsVmConfigSpec.info.key = VM;
    drsVmConfigSpec.info.enabled = false;        
    drsVmConfigSpec.info.behavior = VcDrsBehavior.manual

    var VcClusterDrsVmConfigSpecArray = new Array() ;  
    VcClusterDrsVmConfigSpecArray.push(drsVmConfigSpec);      
    var clusterConfigSpec = new VcClusterConfigSpecEx();
    clusterConfigSpec.drsVmConfigSpec = VcClusterDrsVmConfigSpecArray

    System.log("Setting DRS setting for vm : " + VM.name + " on cluster " + Cluster.name+" to manual.");
    var task = Cluster.reconfigureComputeResource_Task(clusterConfigSpec, true);
    return task;

}
function SetVMToDefault(VM)
{
    var myVM = new VcManagedObjectReference();
    myVM.type = "VirtualMachine";
    myVM.value = VM.id;

    var drsVmConfigSpec = new VcClusterDrsVmConfigSpec();                      
    drsVmConfigSpec.operation = VcArrayUpdateOperation.remove;
    drsVmConfigSpec.removeKey = myVM;

    var ClusterDrsVmConfigSpecArray = new Array();  
    ClusterDrsVmConfigSpecArray.push(drsVmConfigSpec)
    var clusterConfigSpec = new VcClusterConfigSpecEx();
    clusterConfigSpec.drsVmConfigSpec = ClusterDrsVmConfigSpecArray
    
    System.log("Restoring defualt DRS setting for vm : " + VM.name + " on cluster " + Cluster.name);
    var task = Cluster.reconfigureComputeResource_Task(clusterConfigSpec, true);
    return task;
}

var VM =GetVMByUUID();

if (VM != null)
{
    // Get Cluster of VM.
    var Cluster = VM.runtime.host.parent;
    if (VerifyDRSEnabled(Cluster) == true)
    {
        if (State == true)
        {
            var Task = SetVMToManual(VM);
        }
        else
        {
            var Task = SetVMToDefault(VM);
        }
    }
}
    

Hope this can help you out.