Enable vCenter High Availability with vRealize Orchestrator
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.
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.
// 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!