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.
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?
Because We have some very critical VMs with 500GB + RAM and we made a ESXi host for specific VMs because of their critically.
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.
But how to fix the Cluster or host name before VM provisioning ?
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.
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.
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.
You can provision to a ESXi host in vRA using these custom properties:
VirtualMachine.Admin.ForceHost
VirtualMachine.Admin.HostSelectionPolicy: EXACT_MATCH
I do not want to provision a Host using VRA.
I need to provision a Vm in a specific ESXI Host using VRA.
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
Thanks Mate !
Allow me some Time to check it. I will keep you posted.
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.