Caution: Articles written for technical not grammatical accuracy, If poor grammar offends you proceed with caution ;-)
It seem that there is a bit of confusion around using vCO workflows with multi-machine blueprints. Before I discuss how to build vCO workflows for multi-machine blueprints I want to discuss the differences between single machine and multi-machine blueprints and how they relate to each other.
Single Machine Blueprints
Single machine blueprints are pretty straight forward. When a custom property is defined on a single machine blueprint it only affects that machine. Makes sense right? When we trigger a vCO workflow to run during a state transition of a single machine it interacts with only that machine. It is important to be mind full of the vCO workflows that are assigned to single machine blueprints that may be used as a component machine of a multi-machine blueprint.
Multi-Machine Blueprints
Multi-Machine blueprints are extremely versatile allowing single machine blueprints to be grouped together for and requested in a single deployment. They are so versatile that you can add single machine blueprints of different types that are possible deployed to different types of Endpoint and across geographies. This however also makes them somewhat complex requiring you to be careful and thoughtful as to how you structure custom properties and the vCO workflows that you may choose to run on them.
Custom properties that are defined at the Multi-Machine blueprint are passed down to the component virtual machines that are a part of them. This can be very useful, but can also be a bit dangerous. Take the hostname property. If we define a hostname using this property at the Multi-Machine level it will cause chaos during the deployment and cause the deployment to fail because all machine will inherit the property and the value and ultimately have the same name.
This is the case with any different properties when used at the multi-machine level. You also need to be mindful of the effect of that property across different platform, provisioning types as well as geographies. This becomes even more complicated when executing state transition workflows that run vCO workflows. If you attach a workflow to the multi-machine it will in turn become attached to every component machine as well. This can be very useful if you want to execute the workflow on every component machine, however if that workflow is utilizing an entity that doesn’t exists at the parent multi-machine level it will again cause chaos for your deployment. The good news is it doesn’t have to as long as the vCO workflows are built to support the intended result.
In the following walk-through I will be using the Custom vCenter Folders Extension to demonstrate what you can do to account for the Multi-Machine and Single Machine aspects of vCO workflows.
Building a vCO workflow to account for Single and Multi-Machine Deployments
The first workflow we will be looking at is the Set Custom vCenter Folder Name Workflow. This is the meaty part of the Custom vCenter Folders Extension. This workflow was designed so it could be attached to a single machine blueprint and have a defined folder scheme suited for a single machine deployment. It however can also be defined on a Multi-Machine blueprint as well. When defined on a Multi-Machine blueprint the properties at the Multi-Machine level will override those defined on single machine component vm that is part of the Multi-Machine service.
There are some things that needed to be considered when doing this. The workflow needs to understand if it is running on the parent or the component vm for a number of reasons. When run as part of a Multi-Machine blueprint it can be used to place all the deployed component VM’s into a folder named after the parent. If that were to run against the parent VM it would cause the workflow to fail because the parent doesn’t have a parent and the workflow needs to know the name of the parent to understand what it needs to name the folder.
The other aspect is the workflow is designed to remove the folder only if it’s a folder for a multi-machine application deployment. If it were to try and remove the folder when run during a signle machine deployment it would cause chaos as well. Partially because the folder to be removed is based on the name of the parent container which doesn’t exist on a single machine deployment. Below is an over view of the workflow that we will be going through.
To start the workflow an action named “getVirtualMachineEntity” is run that simply looks up the virtual machine entity information from the IaaS from the machine GuiD that is passed to vCO form the vCAC worflow stub. Once we have the virtual machine entity we pass it over to a scriptable task named “Get VM Properties” to then grab all the custom properties associated with the virtual machine.
Next is where we start to make decisions as to what kind of virtual machine deployment we are dealing with. Using a custom decision named “Is Component Machine” we use values that we obtained from the virtual machine entity to determine if it is a component of a Multi-Machine or not. The code inside this custom decision is pretty simple.
var isComponent = vmEntity.getProperty(“IsComponent”);
return isComponent == 1;
The code simply pull the property value for IsComponent associated with the virtual machine. This is a value associated with the machine that is set to 0 if it is not a component machine and 1 if it is. In the above workflow if the value is one the decision is true and the workflow follows the green path and then goes on to setting what it needs to setup the custom folder for placement. This includes the next scriptable task which simply grabs the value that was defined for the property Custom.vCenterFolder.Scheme. It will then feed that into an action named replaceVirtualMachinePropertiesWithValueInString. This action is one that Tom Bonanno created and it is what translates the scheme to it’s desired form. Basically translates {string1}{string2}{string3} to the values defined in the properties that were set in vCAC. It them runs another scriptable task that setups properties to be written back to vCAC and calls another workflow to write them back. In the case of this workflow the property that it writes back is VMware.VirtualCenter.Folder with the appropriate folder path and it lets vCAC handle the creation of the folder and the placement of the VM’s into the folder.
If it were it were to fail I then need to determine if it’s a single machine or a parent machine both of which would have failed my first check. I do this with another custom decision. Again the code for this decision is pretty simple.
var childEntities = vmEntity.getLink(vcacHost, “ChildVirtualMachines”);
return childEntities.length == 0;
Here I’m using an array that contains the children virtual machine of a multi-machine blueprint and checking to see if the array is empty or not, if it is empty then the decision is true and I have determined that this is a single machine being deployed and send it down the same path as I would the component machines. If it is false I have determined that it is a parent machine and proceed on to write a property back to the Multi-machine parent. The value that I’m sending back is the property that will invoke the workflow to delete the folder that was created if the Multi-Machine service is destroyed.
Next I am executing an action I built to formulate what the name of the NSX appliance would be if one were to exist and then feed it into a get virtual machine workflow to look up the NSX appliance virtual machine. I then use another custom decision to determine if an NSX appliance actually does exist. IF one does I then write another custom property back to the Multi-Machien parent to run the workflow that moves the NSX edge to the created folder during the MachineProvisioned state transition workflow.
The moral do this whole story really is the custom decisions that are used to check to determine if it “IsComponent” and if it has “ChildVirtualMachines” with these two desitions I can account for Multi-Machine Blueprints, Single Blueprints, and even go on to determine if NSX is configured.
You may be asking why go through all that to not write the VMware.VirtualCenter.Folder property to the parent machine. In the grand schee of things it wouldn’t matter if I wrote the property back, but what does matter is when I lookup the parent virtual machine name it would fail on the parent machine because it doesn’t have a parent. Also I could have taken the short road and wrote just defined the property to remove the multi-machine folder in vCAC and has it trigger for the component machines as well, however doing so would cause a number of workflow failures as well. The workflow would have run for every component machine and caused errors that the folder didn’t exist for all workflows after the initial one. With this method it only runs one time once the Multi_Machine parent is destroyed.