Are you sick of the Event Broker yet? ME NEITHER!!! In this post we illustrate how to utilize the Event Broker to send custom html emails. Using vRealize Automation 7 to create Custom Email Notifications with the Event Broker your usability and customer satisfaction can improve!
It’s well known that you can set up out of the box notifications from vRA and thankfully in version 7 it’s on by default but there are still many customers asking me for improved customizable emails vs. what is posted in this kb.
So without further ado here’s the example video!
You can download the package used here from this link
For the simple comparison sake let’s start with the out of the box templates. It’s a good example of nothing custom. Very informative and great content.
“I want something more like this that I can play with and customize based on custom properties or other specific content”
We will start by editing the workflow Send custom notification – State Transition
Change the parameters to meet your environment needs
A quick overview of the schema as you can see we collect data, make a decision and either send or not based on that decision.
Let’s edit the Get Properties
In this scriptable task we are using the standard examples to collect the properties and we are also building the logic for whether we send an email and what that email content is.
Here’s the full script that I used in the screens above I’ve highlighted a few of the excerpts you may want to adjust. Examples of what you may want to change are the content of the email (Logo is a good example). You could also uncomment any of the lines between requested and activated if you wanted to give updates at each state.
var executionContext = System.getContext();
System.log(“BlueprintName: ” + payload.get(“blueprintName”)) ;
System.log(“ComponentId: ” + payload.get(“componentId”)) ;
System.log(“ComponentTypeId: ” + payload.get(“componentTypeId”)) ;
System.log(“EndpointId: ” + payload.get(“endpointId”)) ;
System.log(“RequestId: ” + payload.get(“requestId”)) ;
System.log(“VirtualMachineEvent: ” + payload.get(“virtualMachineEvent”)) ;
System.log(“WorkflowNextState: ” + payload.get(“workflowNextState”)) ;
var lifecycleState = payload.get(“lifecycleState”) ;
System.log(“State: ” + lifecycleState.get(“state”)) ;
System.log(“Phase: ” + lifecycleState.get(“phase”)) ;
System.log(“Event: ” + lifecycleState.get(“event”)) ;
var machine = payload.get(“machine”) ;
System.log(“ID: ” + machine.get(“id”)) ;
System.log(“Name: ” + machine.get(“name”)) ;
System.log(“ExternalReference: ” + machine.get(“externalReference”)) ;
System.log(“Owner: ” + machine.get(“owner”)) ;
System.log(“Type: ” + machine.get(“type”)) ;
System.log(“Properties: ” + machine.get(“properties”)) ;
var vRAVmProperties = machine.get(“properties”) ;
if (vRAVmProperties != null) {
var log = “”;
log += “vRA VM properties :n”;
var array = new Array();
for each (var key in vRAVmProperties.keys) {
array.push(key + ” : ” + vRAVmProperties.get(key));
}
array.sort();
for each (var line in array) {
log += “t” + line + “n”;
}
System.log(log);
}
var IP = vRAVmProperties.get(“VirtualMachine.Network0.Address”);
var OS = vRAVmProperties.get(“custom.os”)
System.log(“IP = ” + IP);
System.log(“OS = ” + OS);
if (OS == ‘linux’){ var ipUrl = “ssh://” + IP;}
if (OS == ‘windows’){ var ipUrl = “rdp://” + IP;}
System.log(“ipUrl is ” + ipUrl);
var ls=lifecycleState.get(“state”)
if (ls == ‘VMPSMasterWorkflow32.Requested’){ var subState = “Your self service request has been submitted”;}
/*if (ls == ‘VMPSMasterWorkflow32.WaitingToBuild’){ var subState = “Your self service request is waiting to be built”;}
if (ls == ‘VMPSMasterWorkflow32.BuildingMachine’){ var subState = “Your self service request has been successfully built waiting on activation”;}
if (ls == ‘VMPSMasterWorkflow32.MachineProvisioned’){ var subState = “Your self service request is provisioned waiting on activation”;}
*/
if (ls == ‘VMPSMasterWorkflow32.MachineActivated’){ var subState = “Your self service request is activated and ready for use”;}
/*if (ls == ‘VMPSMasterWorkflow32.DeactivateMachine’){ var subState = “Your self service request has been deactivated and being torn down”;}
if (ls == ‘VMPSMasterWorkflow32.UnprovisionMachine’){ var subState = “Your self service request is unprovisioned and awaiting disposal”;}
*/
if (ls == ‘VMPSMasterWorkflow32.Disposing’){ var subState = “Your self service request has been completely disposed”;}
System.log(“Your subState is ” + subState);
if (subState != null){
System.log(“Setting the to email”);
var emailRequired=”true”;
var toAddress = machine.get(“owner”);
var subject = subState ;
System.log(“Building content line by line”);
content = ‘<img src=”https://extendingclouds.com/wp-content/uploads/2016/04/logo_BBR_003-3.jpg” alt=”biteback logo”>’ +
‘<h2>Thank you for your request!</h2>’+
‘<p>This is an email to let you know your request is in process and you will get updates throughout</p>’ +
‘<p></p>’ +
‘<h3>Your request for ‘ + payload.get(“blueprintName”) + ‘ ‘ + subState + ‘ </h3>’ +
‘<p></p>’ +
‘<ul>’ +
‘<li>Your machine is named: ‘ + machine.get(“name”) + ‘ </li>’ +
‘<li>Is being provisioned with the following CPU: ‘ + vRAVmProperties.get(“VirtualMachine.CPU.Count”) +
‘, RAM: ‘+ vRAVmProperties.get(“VirtualMachine.Memory.Size”) +
‘, and DISK: ‘ + vRAVmProperties.get(“VirtualMachine.Disk0.Size”) + ‘ </li>’ +
‘<li>Will be available at the following IP Address: <a href=”‘ + ipUrl + ‘”> ‘ + ipUrl + ‘</li>’ +
‘<li>Will expire in ‘ + vRAVmProperties.get(“__Cafe.Request.VM.LeaseDays”) + ‘ days</li></ul>’;
}else{
System.log(“Canceling email send”);
var emailRequired=”false”;
}
Next log into the vRA console as an administrative user and go to Administration -> Property Dictionary -> Property Groups. If you followed other post such as Enabling the Event Broker you should already have a property group that passes the properties at the different state changes.
If not create one with the following entries.
Now go to the Design and select the blueprint you will be requesting
Click on the blueprint go to properties tab and then the custom properties. If you don’t already have it create a new property custom.os with a value of the operating system linux or windows *NOTE CASE SENSITIVE. This is part of the code we highlighted earlier which decides if we pass SSH or RDP
Finally we’ll create the subscription by going to Administration -> Events -> Subscriptions -> +New
Select machine provisioning
Run based on conditions. We do this because we want it to only run once per state and to only happen when that state phase is complete (POST)
Select Data – Lifecycle State – State phase
Equals -> POST
Select the workflow “Send custom notification – State Transition”
Just click next
Then publish the new subscription
Now cross your fingers, hold your breath, what ever it is you do to hope it works. Go to the catalog and request your blueprint.
Go back to your vRO instance and review the workflow as it runs (be patient).
Request will fire the workflow and send your custom notification
Building state will fire the work flow but will not send the notification. This is all defined in our scriptable task above.
Now you have successfully gotten your own custom emails using the event broker method. Stay tuned for part 2 which will address a know issue when using software components.
39 comments
2 pings
Skip to comment form
This works if you aren’t using software components. 🙂 What if you want to do with a Xaas blueprint and send at the very end after software component installs. From what I can The EBS is only good when using a blueprint with no software components, otherwise a person will get an email in the middle of their build.
In the current version of the event broker it is accurate that our final state and phase do not include the post software components. This is something we are addressing but there is a simple work around that I will be posting which uses the post approval. That will be the part 2 which I’m sure everyone will enjoy 😀
Hi Gary,
thank you for this another great post! The tutorial is really informative, however, it is not going to work in every environment. Specifically in those environments where the username+domain-name is not the same as the valid email address. See my screenshot here: http://pekar.s.cnl.sk/sandbox/Screenshot%20from%202016-05-23.png
Referring to this screenshot, the workflow will send the notification to jd123ab@vsphere.local instead of john.doe@test.com
Do you know any other property which will refer exactly to the email address?
Adrian,
Yes that’s true in environments like your example this method does offer a new level of complexity. There are no actual properties that list the user email rather than the owner in the payload passed to vRO. In your example you will need to do some conversion methods. I’m assuming the users are stored in Active Directory and have email provided in their user properties, correct?
Yes, that’s right. All our users are in a MS AD where they have the department, userID, emails, etc. (we are a university). Right now I am studying how to call an AD query within your shared workflow. So far your posts inspired me a lot! Thank you!
Great! I’m glad it helped and good luck!
I figured it out. Just leaving here my solution if anyone else would need a hint how to configure the AD with your workflow.
Prerequisites:
1. Configure AD
2. Set Default AD (“Configure AD plug-in options” – workflow name is a bit misleading) – needed for the way how I query AD.
Code for AD query:
#
AllUserData = ActiveDirectory.searchExactMatch(“User”,machine.get(“owner”));
username = AllUserData[0].getAttribute(“displayName”);
System.log(“Username: ” + username);
login = AllUserData[0].getAttribute(“sAMAccountName”);
System.log(“Login: ” + login);
email = AllUserData[0].getAttribute(“mail”);
System.log(“Email: ” + email);
#
Once again. Thank you Gary!
Where in the script do you drop this?
Cameron, I’m confused by your question. Where in the script do you drop what?
Where in the Get properties script do you put the AD query.
To do a user lookup in AD you won’t do it directly in the property collection script. You will set a variable with the userID from the properties as an output and then run a Powershell workflow that uses the user variable and finds the email address. Then you can pass the result to send the email.
Hi Adrian,
Using vRA 7.0.1 I do this :
var authClient = cafeHost.createAuthenticationClient();
var principalService = authClient.getAuthenticationPrincipalService();
var tenant = “vsphere.local”;
…
if (subState != null){
System.log(“Setting the to email”);
var emailRequired=”true”;
var owner = principalService.getPrincipal(tenant, machine.get(“owner”));
var toAddress = owner.getEmailAddress();
//var toAddress = machine.get(“owner”);
I works for me, hope the same to you !
Cheers,
Tim.
Hi,
Thanks for your article, very instructive.
Do you think it is possible to do the same with a blueprint containing 2 VM+ ? I would like to send only 1 email notification containing information about both VM.
The issue is that the workflow is linked to the Event topic “provisionned machines”. For a blueprint containing 2 VM, there will be 2 events and therefore 2 workflows call.
I can’t find a way to build a unique email notification. Moreover, the information from both VM are independant (2 ayload from different event).
Thanks in advance.
Michel,
Sorry to say in the current version theirs no way to tie to or execute something based on the deployment (multiple machines) as opposed to each individual. That said it’s a known short coming and will be something we address in the near future. Now with that said there are teams at VMware that have done creative things that detect if the VM is part of a multiple machines and execute single workflows after collecting data. It’s really a hack though.
Hi Gary,
Thanks for your answer ! 🙂
Couldn’t really get all of the information about de VMs and and put them into a unique email. But I found a way to prevent sending multiple notifications for a deployement :
– tagging each VMs (with custom properties) of the deployement
– modified the current workflow to detect if single or multi VM service, if multi VM, send 1 notification just for the first VM.
– The email says only that the user will by the administrator.
See this is the beauty of the vRA extensibility story. As you found there are a few different ways to accomplish your task and while it may not yet be out of box it’s pretty easy to get a working solution! Hence my love for the Event Broker, vRO and how we are progressing with our automation stack. Thanks for following and sharing your solution!
Hi, Gary
Is there any way I can modify the approver’s email instead of the requester’s?
I would also like to list storage size by tier(bronze,silver,gold) since we are using storage reservations.
I only see a property for total storage.
Thanks!
Bob
Bob, what you will want to do is use the Event Broker with Property Dictionary. Have a required drop down box on the request which has the user select the tier. The at Pre-Requested use my https://extendingclouds.com/vrealize-automation-7-enabling-the-event-broker-part-2/
which then you can update the reservation policyID and deploy to different storage reservations.
Please elaborate on your use case around approver email.
Gary,
I have already enabled the event broker. The user can set the storage reservation policy from the storage tab per virtual disk. I would like that information displayed in an approver’s email for each disk and reservation policy. By default, only the sum of the capacity is shown in the email.
Thanks
If you’re looking for the approval email it may be best to use the https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2102019
That said you could offer an approval workflow that uses custom email to pull out the storage reservation policy.
Hi again Gary,
The custom email notifications workflow is deployed.
But do you know if there is a way to modify an already deployed workflow “on the fly” ?
For example, I needed to add new content on the custom email notifications. I went to vRO to add the new content on the custom email notifications workflow. Then I requested a new VM on vRA to check the new email content. The email was not sent at all because of errors in workflow. So I went back to vRO to solve the issues. So if another user requested a VM at the same time, he would not get any notifications, which is an issue.
I was thinking of duplicating the current workflow and doing modifications on the 2nd workflow with an added condition “if admin request then do workflow” to avoid sending duplicate notifications.
What do you think ? Is there a better way to do it ?
Thanks in advance, again.
Michel,
Yes since you have a working method I would agree you should duplicate the workflow and then start your testing. Since I don’t fully know the use case it’s hard for me to say exactly how I would do it but based on your description I would do one of two things, I would either add logic to the scriptable task which would alter the email notification, or I would include a decision in the workflow that would choose a path based on “if admin requested”. Basically you could use the existing template and at the don’t send portion you could set that for the admin use case.
Again, I don’t know for sure but based on what I understand that’s how I would make workflow. Let me know if you need any additional support.
Hi,
This is just what I’m looking for! Does this work with vRA 7.1? On importing the package I receive an error message “Unable to Import, server version is greater…” on the Send Notification 0.1.2 file element. Thanks!
Try this post, I updated for 7.1
https://extendingclouds.com/vrealize-automation-7-custom-email-notifications-with-the-event-broker-copy/
Gary,
Thank you for this wonderful write up. It was very helpful. I have integrated vRealize Business with my vRA and would like to include the machine’s Daily Cost into the email. Would you have any input onto how I could do this?
Prior to the 7.2 release this was a difficult task as you have to make an API call into the vRB components in order to pull the daily costs. I’m not sure if this has been resolved with the 7.2 release.
Interestingly enough. If you use the vmware templates https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2147429 the costing data does work. However, I find your solution for sending custom emails using the event broker more desirable. As I have better control of when in the work flow to send the emails. Also editing the email templates is cumbersome.
A contact with VMware PSO passed this along to me. However, it is always returning 0 even thought I see it in the data payload
System.log(props);
if(props == null) throw “Input properties object is null! Cannot continue.”;
var machine = props.get(“machine”);
var machineProps = machine.get(“properties”);
var username = machine.get(“owner”);
var resourceID = machine.get(“id”);
var resourceName = machine.get(“name”);
var blueprint = props.get(“blueprintName”);
var accountNumber = machineProps.get(“Index.Number”);
System.log(“Looking for resource: ” + resourceID);
var resource = null;
var counter = 0;
var maxCount = 30;
while(resource == null)
{
if(counter >= maxCount) break;
for(var i in vcacHosts)
{
var host = vcacHosts[i];
var client = host.createCatalogClient();
var resourceService = client.getCatalogConsumerResourceService();
var pr = new vCACCAFEPageOdataRequest(1, 100000);
var resources = resourceService.getResourcesList(pr);
for(var res in resources)
{
var currentRes = resources[res];
if(currentRes.providerBinding != null)
{
if(currentRes.providerBinding.getBindingId() == resourceID)
{
resource = currentRes;
break;
}
}
}
if(resource != null) break;
}
if(resource == null)
{
counter++;
System.log(“Try #” + counter + “: Resource not found yet, sleeping 5 seconds”);
System.sleep(10000);
}
}
if(resource == null) throw “Unable to find resource within the allotted time!”;
System.log(“Found resource: ” + resource);
var dailyCost = resource.resourceData.get(“MachineDailyCost”);
var yearlyCost = Number(dailyCost) * 365;
content = ContentTemplate;
content = content.replace(“$requester”, username);
content = content.replace(“$account”, accountNumber);
content = content.replace(“$blueprint”, blueprint);
content = content.replace(“$cost”, yearlyCost);
System.log(“Username: ” + username);
System.log(“Blueprint: ” + blueprint);
System.log(“Account #: ” + accountNumber);
System.log(“dailyCost: ” + dailyCost);
System.log(“Yearly Cost: ” + yearlyCost);
System.log(“Email content:”);
System.log(content);
//throw “fail”;
payload>machine>properties> __DailyCost : {“type”:”moneyTimeRate”,”cost”:{“type”:”money”,”currencyCode”:”USD”,”amount”:10700.8684},”basis”:{“type”:”timeSpan”,”unit”:4,”amount”:1}}
Ok so reading through this it looks to me like the PSO resource is doing the look up through a CAFE request (which is a vRO object). Are you pulling the daily cost? If so I would just pass it into an attribute and use it to write the email.
No It’s not. “var dailyCost = resource.resourceData.get(“MachineDailyCost”);” always returns zero. JavaScript is not my forte. Like I Mentioned but may not have been clear. If I use the event Broker to log everything being passed by properties I do see the data I need. “”amount”:10700.8684}” which is returned as an array here. I just have no clue how to pull that out and put it into an attribute I can use.
payload>machine>properties> __DailyCost : {“type”:”moneyTimeRate”,”cost”:{“type”:”money”,”currencyCode”:”USD”,”amount”:10700.8684},”basis”:{“type”:”timeSpan”,”unit”:4,”amount”:1}}
Appreciate the help.
Hello Scott,
You can use VCACCAFEEntitiesFinder to get the CatalogItemRequest.
Once you get the catalogItemRequest , you can quote,rate,cost from respectively. I have already implemented that and it’w working fine.
Thanks,
KM
Hi Gary,
I am getting below error when I run the workflow for state change.
[E] Error in (Workflow:Backup_Notification / Get Properties and apply logic (item1)#39) TypeError: Cannot call method “get” of null
vrA verison is 7.2
Thanks
Sorry for the delay. I am not getting notifications for comments from the site now. Did you get this resolved?
TypeError: Cannot call method “get” of null (Workflow:Send custom notification – State Transition / Get Properties and apply logic (item1)#39)
facing this issue , Please suggest
HI,
When I use the Throw command for a failure in a VRO flow triggered by a EventBroker with a MachineProvision POST it only throws it to the EVENTS logs but if I put it to a PRE it goes to the Event logs and fails the request. Is there a way to get a failure to fail the request in post
Author
If you review the sheet https://docs.google.com/spreadsheets/d/1l1dg6Elx3Z1Z8zPcKjyuUKbBiTP__yCktQ8XB7Sa6SY/edit#gid=1741739736 you’ll see what happens on failure column and it’s operating as expected. In order to make it work the way you are looking for you’ll need to use a workflow in the POST even that detects your failure and forces the event broker to a failed state. You can do that will an output variable to any one of the stages.
hello, the link to download the routine you created is not working.
The form you created is very simple, could you please make it available again?
Thank you very much
Author
Since I don’t have access to play with vRA any longer and I focus on the fun of GCP all I can do is offer this link. It is a back up of all the content I built from my vRA days. https://drive.google.com/file/d/19a0YvNqEySSN3pXV8UNwmt3xHTBn_oy4/view?usp=sharing
Hi Gary, thanks for this nice article. The link you have to the file download no longer works. Is there any way I can get that file.
Thanks a lot.
Author
Since I don’t have access to play with vRA any longer and I focus on the fun of GCP all I can do is offer this link. It is a back up of all the content I built from my vRA days. https://drive.google.com/file/d/19a0YvNqEySSN3pXV8UNwmt3xHTBn_oy4/view?usp=sharing
[…] this post with that because what I’m going to show you here may not be as valuable as the custom notifications, or the prepare a windows template for software components. However with Sample Exchange growing […]
[…] to solve the one hole I’ve found with the event broker in vRA 7. As you all know if you read vRealize Automation – Custom Email Notifications with the event broker there are lots of great ways deal with custom html notifications. The event broker exposes all of […]