One of the things I’m working on as part of a customer project is adding an option to vRA blueprints to allow automatic configuration of SRM protection.
The requirements for this piece of work are:
- Add a tickbox to the vRA request form to allow the user to specify that DR protection is required for the VM
- Create a Protection Group and Recovery Plan for the VM as part of the vRA request if the box on the request form is ticked
- Configure the Recovery Plan steps to include changing the IP address of the VM during the failover
- When the VM is destroyed in vRA the SRM configuration (Recovery Plan and Protection Group) should also be destroyed
Whilst it isn’t required for this proof of concept a future enhancement could include a day 2 action within vRA to allow the user to initiate the SRM failover of the VM.
This will be the first part in a series of posts covering the steps required. This post covers enabling replication using vSphere Replication. Part 2 (coming soon) will focus on creating the Protection Group in SRM and adding the VM to the new group.
I’m using a combination of vRA 7.5, vRO 7.5 with the SRM 8.1 and vSphere Replication Plugins installed and the api of SRM. I’ve added the vCenters, vSphere Replication and SRM instances from both the Protected and Recovery Sites to my vRO instance.
SRM Plugin Limitation
Version 8.1 of the SRM vRO plugin does not provide a method for the creation or modification of Recovery Plan steps for changing IP addresses on VMs. This is expected to be provided in a later release, but the only solution currently is to use the SRM API to perform these steps. Therefore I have also added my SRM servers to vRO as REST hosts. I initially experimented with using a SOAP connection to SRM. The SRM API documentation points to SRM using a SOAP API, however this did not seem to provide all of the functionality I needed. By using REST I am able to send XML payloads to the API and get additional values in the response or headers.
The Solution Design
Since SRM requires a VM to be present in vCenter before it can be added to its inventory the logical start point for any automation is as part of the vRA lifecycle during the post VM provisioning lifecycle stages. I’m going to use the Machine Provisioned POST lifecycle stage. I know that I will have easy access to the VM information from the vRA payload. It also means that all key internal vRA activities will have been completed on the vRA by this point in the lifecycle.
Thinking about the high level process for protecting a VM the workflow will need to perform the following high level steps:
- Retrieve the VM object and key values from the vRA payload
- Retrieve the SRM Protection Folder (this is the parent object for most SRM related inventory objects)
- Configure replication for the VM in vSphere Replication
- Create a new protection group in SRM for the VM based on vSphere Replication
- Add the VM to the new protection group
- Create a new recovery plan in SRM and add the new protection group to it
- Add the IP address change to the steps in the Recovery Plan
- Update custom properties in vRA on the VM with the configured settings
The last step is optional, but I personally like to store key pieces of information in vRA, you never know when a request will come in for an additional process where having this information readily available saves you time.
Configuring Replication for the VM
Looking at the workflows provided by the vSphere Replication plugin we can see that there is a workflow named Configure Replication. The description of this workflow – “Configure a virtual machine for replication from this site to another vSphere site” confirms that it provides the functionality we need. Checking the inputs tab of the workflow shows that it requires a few pieces of information:
- vSphere Replication local site
- vSphere Replication remote site
- VM to protect
- Target datastore for the replication
- The RPO in minutes that applies to the VM
Optionally we can also specify whether to enable Guest OS Quiescing, Network Compression and Point in Time instances for the VM. For my use case none of the optional values need to be enabled so I will be leaving them set to the default values.
So, how do we find the values needed for setting up replication? Well we could predefine them within the vRO workflow, but if we have multiple sites this wouldn’t work. Let’s start with the vSphere Replication local and remote sites.
Getting the VR:Site and VR:RemoteSite values
The vSphere Replication plugin provides documentation within the vRO API explorer, however I prefer to use vroapi.com to view the information. I find the website easier to use since it clearly lists the methods that can be performed on an object, but more importantly the methods that return the selected type of object. Under the vSphere Replication plugin section we can see that there is a VR:Site class. Checking the Returned By section we find that there is a method VRPluginConfig.getSites() which will return an array of VR:Site objects. This will contain the local and remote VR site objects we need.
Now we have the two sites we need a way to identify which of the values returned is the local site, and which is the remote site. The VR:Site object has a property VcInstanceUuid which is the unique id of the vCenter it is associated with. We can get this same value from our VM by traversing its sdkConnection property and retrieving the instanceUuid property. If the two values match then we know we have our local site.
To get the remote site value we can use the method getVcRemoteSites on the VR:Site object. Testing this method we actually find it returns the same two vCenter values as the VRPluginConfig.getSites method does, but on closer inspection we can see that the object type is VcRemoteSite. This is because vSphere Replication is configured to allow replication between the vCenters and also within the same vCenter, so has two remote vCenter instances. To make sure we get the correct site we can check the VcInstanceUuid property of each of the results and select the one which does not match the value from our VM.
Now we have our two sites lets work on getting the target datastore.
Getting the target datastore value
The VcRemoteSite object has a method getDatastores() which returns an array of VR:RemoteDatastore. For my use case I have a standard naming format that I can use to identify the target datastore. So by retrieving the name of the datastore the VM is currently running on and changing the site identifier within the datastore name, I have the name of my target datastore. I can now loop through the values in the array until I find an entry which has a matching name.
If a similar approach doesn’t work for your environment, consider creating a Configuration Element in vRO as a reference table. Create an attribute with the name of the local datastore and assign the name of the associated remote datastore (or the datastore object) as the value. Now you can retrieve the name of the local datastore from the VM, and use the value to query the Configuration Element for the remote datastore.
The workflow structure
Now we have the input values required for configuring replication for the VM using vSphere Replication we can start creating our workflows. Personally I like to group all of the steps related to gathering values from the payload into a single script at the start of my workflow. That way, if any of the values are found the workflow can exit with an error immediately rather than trying to perform an action using the non existent value. So, I’m going to create a parent workflow which will call multiple workflows. The first of these subworkflows will contain the steps we have just worked through to configure replication. Subsequent workflows will be created and added for each of the other tasks we need to perform to complete the configuration of SRM.
So, the first stage of my workflow will be a Scripting Element to retrieve the following values from the payload:
- VM UUID
- Name of the datastore the VM is running on
The list of values required will increase as I add the later steps like configuring SRM into the workflow, but for now all that is required is to assign these values to attributes so they can be used within the component workflows.
I’m not going to cover how to retrieve the values from the payload provided by vRA, but the properties I will be using are ‘VirtualMachine.Admin.UUID’ and ‘VirtualMachine.Disk0.Storage’.
The parent workflow at the end of this first part will look like this
Configure replication component workflow
The first component workflow is for configuring replication in vSphere Replication, it will take the VM Uuid and the Datastore name values from the parent workflow as input parameters.
The output of the workflow will be a vSphere Replication group.
The workflow will start with an action to retrieve the VC:VirtualMachine object using the VM Uuid value from the payload. Remember that we need the VM object to be able to get the information about the vCenter it is running in, so that we can identify our local and remote sites.
This is the code I will use for the action
After getting the VM object I am going to add a Scripting Element, which I’m naming ‘Find the VC Instance UUID’ to retrieve the vCenter instanceUuid value from the VM. The scripting element takes a single input of a VC:VirtualMachine object which is mapped to the virtual machine returned by the action described above. A single output is needed for the UUID value of the vCenter, which will be used in the next part of the workflow. This is the basic code needed:
That is followed by a Scripting Element to retrieve the local and remote sites as well as the target datastore, which I’m naming ‘Find the replication sites and datastore’. The inputs will be the vCenter instance UUID retrieved in the previous step and the name of the datastore retrieved from the payload in the parent workflow. The outputs will be the local and remote vSphere Replication sites and the vSphere Replication datastore. A bit more code is needed this time:
Finally I’m going to reuse the Configure Replication workflow provided by the vSphere Replication plugin (Library>vSphere Replication> Configure Replication>Configure Replication) to perform the configuration.
The workflow requires a few inputs, the vm, site, remoteSite an datastore values are all mapped to attributes we have used in earlier parts of the workflow. The other optional inputs are mapped to new attributes and left with the default values.
The output of the Configure Replication workflow will be mapped to an output parameter so that it can be reused in later component workflows.
Once everything is configured the workflow looks like this
That wraps up the first part of this blog series. Part 2 will cover the next stage of using the replication group we have just created with SRM to create a new Protection group.