Scripting from vCAC Workflows (Southbound)
VCAC is really easy to setup and make 3rd party callouts at different states in the machine’s lifecycle. One of the most common requests we had to implement some very specific logic around VirtualMachine naming standards.
There are multiple ways to make 3rd party callouts natively from VCAC:
- SSH
- Powershell
- RunProcess
- VMware VCO – VirtualCenter Orchestrator (that orchestrates WAY more than just VirtualCenter!!) – this gives you a whole host of ways to interact with our datacenter. With more VMware partners adding additional plugins like ServiceNow, F5, and many more its certainly a great option.
Machine State Overview
Every machine whether a VMware VirtualMachine, MS HyperV, Amazon Public cloud machine or DELL/Cisco/HP Blade can have the same State management capability.
The main Machine States that are usually used when applying custom logic are:
- AwaitingApproval
- BuildingMachine
- MachineProvisioned
- TurningOn/TurningOff
- DeactivateMachine
Custom workflows can be added to run prior or post to the MachineState applying its business logic.
Example – Custom Hostname Workflow
Process flow:
- User requests a machine
- Prior to the machine building a workflow will be called to execute a powershell script and update the machines’ hostname.
- The machine will then start to build with the correct name
How To:
Either create a new workflow using the Visual Studio Designer or use one of the Workflow Stubs that are shipped out of the box. The workflow stub that would be needed in this case is “WFStubBuildingMachine“. To enable this workflow to run add this custom property to the VirtualMachine blueprint you wish to assign this policy “ExternalWFStubs.BuildingMachine”
Using the Visual Studio Addin – Create a new workflow to run in the BuildingMachine State
The Powershell script
# Update VirtualMachine.VirtualMachineName property with new name based on incoming custom properties
$location;
$serverType;
#$Machine object is the VirtualMachine and passed in by the calling workflow
#$Machine.VirtualMachineProperties is populated with all of the VirtualMachines properties and can be a useful way to store metadata, in this case Location & ServerType will be used to form the new hostname
#$MgmtContext object is the connection to the VCAC Database over a RESTFul connection
foreach ( $p in $Machine.VirtualMachineProperties) {
if ($p.PropertyName.ToLower() -eq “location”) {
$location = $p.PropertyValue;
}
if ($p.PropertyName.ToLower() -eq “servertype”) {
$serverType = $p.PropertyValue;
}
}
# Save new machine name to DCAC Inventory
$machineName = $location + $serverType + $Machine.VirtualMachineName
$Machine.VirtualMachineName = $machineName.ToUpper();
if ( $MgmtContext -ne $null ) {
$MgmtContext.UpdateObject($Machine)
$MgmtContext.SaveChanges()
}
Load the script into the Repository
CloudUtil -n ChangeMachineName -f ChangeMachineName.ps1 -d “Change machine hostname”
The Workflow
Open the Workflow to the Custom Code FlowChart where you can add activities.
1) Load the VirtualMachine into the Workflow, use an Assign Activity and store in the variable machine
Linq Query:
machine = mgmtContext.VirtualMachines
.Expand(Function(v) v.VirtualMachineProperties)
.Where(Function(v) v.VirtualMachineID = VirtualMachineId)
.FirstOrDefault()
This query is loading from the Database a VirtualMachine object based on the incoming VirtualMachineId (for context). It is also Expanding the VirtualMachineProperties associated with the machine, by default if we dont do this it will be an empty array. As we wish to retrieve custom properties (Location & ServerType) we must expand.
For information about common Linq queries see this blog
2) Create a local workflow variable “scriptContent” of type String
3) Add the Activity from the CDK GetScriptFromName
assign the following properties to the GetScriptFromName activity:
ScriptName=”ChangeMachineName“
ScriptContent=”scriptContent“
4) Add the InvokePowerShell Activity with the following Properties:
CommandText=scriptContent
PowerShellVariables= we are going to add 2 variables in this collection:
The final workflow will look like this:
Install the workflow into the DCAC Repository and apply the External XML file into the VCAC Application Server.
Summary
Whats cool in my opinion here is the entire VirtualMachine object as well as the REST/DB connection is passed as objects you can use in the script. Any object can be serialised in, the Host or ManagementEndpoint are also quite common so you can connect to 3rd party endpoints and use centralised credentials
March 1, 2013 at 8:17 pm
Hey Tom, nice article, although I am using vCloud Automation Center Designer and the interface looks a bit different from the pictures on your post I was able to complete the workflow.
Do I have to define the property on the blueprint “ExternalWFStubs.BuildingMachine” to enable the execution of the workflow? Thanks.
LikeLike
March 2, 2013 at 6:38 pm
Yes that's correct. With the property name.
The design center is a different tool which creates net new workflows, if you are modifying an out of the box workflow stub then you won't need to do this step.
LikeLike
March 8, 2013 at 9:07 pm
I get into errors every time I try to use the InvokePowerShell activity, the log viewer reports the script cannot run. However I can use the ExecutePowerShellScript without issues, but I still don't know how to pass the virtual machine object to the script. There is a property called MachineId on the ExecutePowershellScript object, any clue on how to pass the VM properties to the script? thanks
LikeLike
March 8, 2013 at 10:26 pm
Actually whats interesting is the ExecutePowershellScript is a wrapper activity over InvokePowershell, so you are actually using it. However if you use ExecutePowershell script and pass in the MachineId property then an powershell property called “Properties” of type Dictionary is passed in, meaning all custom properties of the VirtualMachine can be referenced using $Properties. Ie:
#Get the Network IP Address of a machine
$Properties[“VirtualMachine.Network0.Address”]
However the problem with this is that you only get machines MetaData (properties from the VirtualMachineProperties table), not actual properties of the Machine itself (Ie: values from the VirtualMachine table), which is why I use the InvokePowershellActivity because you can pass the entire VirtualMachine object and all properties can be referenced by $Machine.VirtualMachineProperties.
Perhaps log a support ticket to find out what is wrong with your IPA.
Cheers
LikeLike
March 11, 2013 at 5:51 pm
Thanks, I have opened a SR with VMware.
LikeLike
March 12, 2013 at 2:52 pm
Hi Tom, is there any reference document for vCAC objects? When I pass $Properties through ExecutePowershellScript I get something like this: System.Collections.Generic.Dictionary`2[System.String,System.String]
Thanks.
LikeLike
March 12, 2013 at 3:42 pm
As you can see the type is Dictionary. The key is a name of a virtualmachine custom property, so for example to get the IP Address:
$ipAddress = $Properties[“VirtualMachine.Network0.Address”]
LikeLike
April 19, 2013 at 12:22 pm
and do not forget to select the “isScript” checkbox on the InvokePowerShell.
Thanks Tom this post was really useful to me !
Ben
LikeLike
May 28, 2013 at 8:22 pm
Hello Tom,
thank you a lot for this article. I was able to tie hostnames to ip addresses for a customer.
In your example are three errors. It would be nice if you could correct them:
On the powershell [x]iscript need to be ticket
ScriptContent=”scriptContent” the quotes are wrong because it is a variable not a string.
The first problem caused the following error message: Workflow “WFStubBuildingMachine” failed with the following exception: The term 'power shell script here' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. The second lead to a validation error.
Thanks again you helped me a lot. And my workflow based on the ip address is working using the wfstub buildmachine.
Cheers,
Thomas
LikeLike
October 18, 2013 at 5:16 am
Hi Tom, is there a reason why you actually “insert” the mgmtContext into the script as a variable instead of passing it down to the script as an input parameter? In the latter case you can test and use the scripts outside of workflow runs which makes it easier to debug (at least for me). Ronald
LikeLike
September 22, 2015 at 8:55 am
Your posts is really helpful for me.Thanks for your wonderful post. I am very happy to read your post. It is really very helpful for us and I have gathered some important information from this blog. servicenow training in hyderabad ,splunk training in hyderabad
LikeLike
December 13, 2016 at 4:22 pm
I have been reading out a lot of your articles and that i ought to say pretty nice stuff. I will certainly bookmark your internet website
Devops Online Training
Adobe cq5 Training
Dell Boomi Training
LikeLike
January 20, 2017 at 6:26 am
we are offering best sailpoint online training with job support and high quality training facilities and well expert faculty .
to Register you free demo please visit
sailpoint training in hyderabad
LikeLike