Enable vCenter High Availability with vRealize Orchestrator

Written by Sam McGeown
Published on 21/9/2018 - Read in about 3 min (525 words)

Just a quick post today to cover a new vRO action and workflow I’ve uploaded to GitHub that configures vCenter High Availability in the basic mode. This is based on William Lam’s excellent PowerShell module that does the same, but using vRO. I also hope to release a version for the advanced mode based on my PowerShell script in the near future.

TL;DR - package is availabile on GitHub

The workflow itself is pretty self explanatory, with my deployment action, which returns a VC:Task, and the standard “wait for a task to end” action.

Configure vCenter HA workflow

Executing the workflow requires some configuration for the vCenter HA heartbeat network (which must exist as a Distributed Port Group), as well as some details of the vCenter connection, the active vCSA VM and the datastores to clone the witness and passive appliances to (mine are both vSAN). The vCenter SSL thumbprint is the SHA1 thumbprint of the vCenter SSL certificate - I haven’t found a way to programatically get that within vRO.

Once the action runs, vSphere will configure the vCenter Appliance for HA by adding a second NIC on the heartbeat network, then cloning the passive and witness VMs - below is the configured vCenter HA.

The action code itself is a little more complicated, and involves building a series of configuration objects which are then passed to a method on a failoverClusterConfigurator object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Configure Active Node Settings
var activeIPSpec = new VcCustomizationFixedIp();
activeIPSpec.IpAddress = haActiveIp

var activeIPSettings = new VcCustomizationIPSettings() ;
activeIPSettings.SubnetMask = haSubnetMask
activeIPSettings.Ip = activeIPSpec

var activeNetConfig = new VcClusterNetworkConfigSpec();
activeNetConfig.NetworkPortGroup = haNetworkPortGroup;
activeNetConfig.IpSettings = activeIPSettings;

var serviceLocator = new VcServiceLocator();
serviceLocator.credential = new VcServiceLocatorNamePassword();
serviceLocator.credential.username = vCenterUser;
serviceLocator.credential.password = vCenterPassword;
serviceLocator.instanceUuid = vCenterSDK.instanceUuid;
serviceLocator.url = "https://"+vCenterSDK.sdkId;
serviceLocator.sslThumbprint = vCenterSSLThumbprint;

var activeNodeSpec = new VcSourceNodeSpec() ;
activeNodeSpec.ActiveVc = vCenterVM;
activeNodeSpec.ManagementVc = serviceLocator;

// Configure Passive Node Settings
var passiveIPSpec = new VcCustomizationFixedIp();
passiveIPSpec.IpAddress = haPassiveIp;

var passiveIPSettings = new VcCustomizationIPSettings() ;
passiveIPSettings.SubnetMask = haSubnetMask;
passiveIPSettings.Ip = passiveIPSpec;

var passiveNodeSpec = new VcPassiveNodeDeploymentSpec() ;
passiveNodeSpec.folder = vCenterVM.parent;
passiveNodeSpec.nodeName = vCenterVM.name+"-passive";
passiveNodeSpec.ipSettings = passiveIPSettings;
passiveNodeSpec.datastore = haPassiveDatastore;

// Configure Witness Node Settings
var witnessIPSpec = new VcCustomizationFixedIp();
witnessIPSpec.IpAddress = haWitnessIp;

var witnessIPSettings = new VcCustomizationIPSettings() ;
witnessIPSettings.SubnetMask = haSubnetMask;
witnessIPSettings.Ip = witnessIPSpec;

var witnessNodeSpec = new VcNodeDeploymentSpec();
witnessNodeSpec.folder = vCenterVM.parent;
witnessNodeSpec.nodeName = vCenterVM.name+"-witness";
witnessNodeSpec.ipSettings = witnessIPSettings;
witnessNodeSpec.datastore = haWitnessDatastore;

var vcHADeploySpec = new VcVchaClusterDeploymentSpec();
vcHADeploySpec.witnessDeploymentSpec = witnessNodeSpec;
vcHADeploySpec.passiveDeploymentSpec = passiveNodeSpec;
vcHADeploySpec.activeVcNetworkConfig = activeNetConfig;
vcHADeploySpec.activeVcSpec = activeNodeSpec;

System.log("Starting deployment task...");

var instanceRef = new VcManagedObjectReference();
instanceRef.type = "ServiceInstance";
instanceRef.value = "ServiceInstance";
serviceInstance = VcPlugin.convertToVimManagedObject(vCenterSDK, instanceRef)

serviceContent = serviceInstance.retrieveServiceContent()
var vcHAClusterConfig = serviceContent.failoverClusterConfigurator;
return vcHAClusterConfig.deployVcha_Task(vcHADeploySpec);

Both the workflow, and the action are available on my GitHub repository here. Ping me on twitter if you find it useful, or have any questions!

Share this post