Create a XaaS in vRealize Orchestrator for vRealize Automation and NSX

This week I have dedicated myself of how to create a Workflow in vRealize Orchestrator inorder to create a XaaS, Anything as a Service blueprint in vRealize Automation.

The problem is this: I have created a multi-machine blueprint in vRA see previous post that creates Windows VMs behind an Edge Loadbalancer. Now I want to make sure that it is only possible to RDP to the VMs by using only the IP address to the LB VIP. So together with NSX micro segmentation make sure to block all RDP connections directly to the VMs and only accept to the LB VIP.

In vRO I have created a REST-API connection against the NSX Manager. Let’s call it nsxmanager.local

After the NSX Manager has been registered in vRO. It is time to create a workflow with scriptable tasks. The scriptable tasks are written in JavaScript together with REST API to fetch information with GET command and to create items with the POST command to the NSX Manager API.

A great thing to have in hand when doing this kind of work is having the VMware NSX Rest API documentation available here is the link.

Also to learn alot on how to work with vRO, Javascript, XML and REST API read this whitepaper from Vmware that describes the construction of the scripting Automation Leveraging NSX REST API. Here is the link to the website where the document can be found plus additional information regarding the subject.

And I also a side from working in vRO am using a standalone REST API client, called Insomnia. So that I am able to test and fetch information of the objects I want to get or post info about as I’m trying to build my code. Here is the link to that application.

Workflow Creation Time:

Next I have Created a new Workflow in vRO that is called ”Create LB IPset, Security Group and Security Policy”.
The Workflow will be built with four scriptable tasks each doing its own separate thing as described in these bulletpoints.

  • Retrieve Edge
  • Add Edge LB IP to IPSet
  • Create Securitygroup with the name of the Edge LB
  • Add the Securitygroup to a Policygroup

Here is what I want to do in each Scriptable Workflow.

 

Retrieve Edge:

Retrieve the Names and Edge IP of the Edge Loadbalancer from NSX with GET command in REST API.

Add Edge LB Virtual IP to IPSet:

Pass the Edge LB IP name and IP onward and create a new IPSet with the name of the Edge LB and add the IP from the Edge in the IPSet.

Create Securitygroup with the name of the Edge LB:

Pass along the IPset Object ID and IPset name to create a Securitygroup with the name of the IPSet and add the IPset ObjectID to the Security Group Created.
This is done with the POST REST API command.

Add the Securitygroup to a Policygroup:

Last GET the name of the PolicyGroup called ”int30 Security Policy” and modify the XML information. and add the Securitypolicy for the Edge IPSet to the Policy.
The Rule that will be created will contain the SecurityGroup ID, the Application ID and Name. For RDP. And set a firewall rule to allow ANY against the Security Group.

My First Scripting task “Add Edge IP to IPSet” looks like this:

var request = restHost.createRequest(“GET”, “4.0/edges/”); //Get all Edge
request.contentType = “application/xml”;
System.log(“Check all Edge – Request URL: ” + request.fullUrl); //Display request URL
var response = request.execute();
if(response.statusCode != 200) throw(“Could not GET edge list ! : ” + response.statusCode + “\n” + response.contentAsString);
var edgelistXML = new XML(response.contentAsString); //Convert response as String
//System.log(edgelistXML)
// Get EdgeSummary node
var EdgeList = edgelistXML.edgePage.edgeSummary;
//Check for EdgeID provisioned by vRA.
var EdgeID = [];
for each (var edge in EdgeList) {
if (edge.description.text() == “Edge provisioned and managed by VMware vRealize Automation”) {
EdgeID.push(edge.objectId.text().toString());
}
}
if (EdgeID.length == null) throw(“No Edge found”);
System.log(“Edge-Id found :”+EdgeID);
//Check for VIP
var EdgeIP = [];
var EdgeName = [];
for each(var ID in EdgeID) {
var request = restHost.createRequest(“GET”, “4.0/edges/”+ID);
request.contentType = “application/xml”;
System.log(“Check VIP on Request URL: ” + request.fullUrl);
var response = request.execute();
if(response.statusCode != 200) throw(“Could not GET edge from ID ! : ” + response.statusCode + “\n” + response.contentAsString);
var edgeconfXML = new XML(response.contentAsString);
EdgeIP.push(edgeconfXML.features.loadBalancer.virtualServer.ipAddress.text().toString());
EdgeName.push(edgeconfXML.name.text().toString());
}
System.log(EdgeIP);

The next Scripting task looks like this:

//This Task takes the Edge Name and Edge IP and Creates the IPSet in NSX
description= EdgeName + ” LoadBalancer enabled Edge IpSet in VRA”;
System.log(description);
//Set the name for the IP Set as IP Set appended to the EdgeName
ipSetName= “IP Set-“+ EdgeName;
ipSetValue= EdgeIP;
System.log(EdgeName +” Loadbalancer VIP is: ” +EdgeIP);
// Prepare the HTTP body as an string with the required
stringbody='<ipset><type><typeName>IPSet</typeName></type><description>’ + description + ‘</description><name>’ + ipSetName + ‘</name><value>’ + ipSetValue + ‘</value><inheritanceAllowed>false</inheritanceAllowed></ipset>’;
// Uncomment the next line to dump the generated string to the debug
//System.debug(“Generated string is: ” + stringbody);
//System.log(stringbody);
// HTTP POST request is prepared using the URL: /api/2.0/services/ipset/scopeId
// Note that “/api” is not shown in the request URL as it’s already set in the endpointconfiguration
// scopeId is globalroot-0
var request = restHost.createRequest(“POST”, “/2.0/services/ipset/globalroot-0”, stringbody);
request.contentType = “application/xml”;
request.execute();
//System.log(request);

The third looks like this:

//This Scriptable task creates a Securitygroup based on the name of the IPSet name and after the Securitygroup is created adds the
//IPSet to the Security Group.
// GET info of IPSET from https://nsx.rtsvl.local/api/2.0/services/ipset/scope/globalroot-0
var request = restHost.createRequest(“GET”, “2.0/services/ipset/scope/globalroot-0”); //List all the IPSets
request.contentType = “application/xml”;
System.log(“Check all IPSets – Request URL: ” + request.fullUrl); //Display request URL
var response = request.execute();
var IpSetlistXML = new XML(response.contentAsString); //Convert response as String
var IpSetList = IpSetlistXML.ipset;
//System.log(IpSetList);
var IpSetID = [];
for each (var ipset in IpSetList) {
if (ipset.name.text() == ipSetName) {
IpSetID.push(ipset.objectId.text().toString());
}
}
if (IpSetID.length == null) throw(“No IpSetID found”);
System.log(“IpSet-Id found: “+IpSetID);
//Create a SecurityGroup based on name on IPset
stringbody='<securitygroup><objectId>’ + ipSetName + ‘</objectId><objectTypeName>SecurityGroup</objectTypeName><vsmUuid>4216ECB4-6001-0631-7E0A-8A052CEA2062</vsmUuid><nodeId>5acf1029-4d59-46cd-84d6-b3edbbeec2bf</nodeId><revision>0</revision><type><typeName>SecurityGroup</typeName></type><name>’ + ipSetName + ‘</name><scope><id>globalroot-0</id><objectTypeName>GlobalRoot</objectTypeName><name>Global</name></scope></securitygroup>’
// Uncomment the next line to dump the generated string to the debug
//System.debug(“Generated string is: ” + stringbody);
//System.log(stringbody);
// HTTP POST request is prepared using the URL: /2.0/services/securitygroup/bulk/globalroot-0
// Note that “/api” is not shown in the request URL as it’s already set in the endpointconfiguration
// scopeId is globalroot-0
var request = restHost.createRequest(“POST”, “/2.0/services/securitygroup/bulk/globalroot-0”, stringbody);
request.contentType = “application/xml”;
request.execute();
//Get ObjectID on Securitygroup created.
//https://nsx.rtsvl.local/api/2.0/services/securitygroup/scope/globalroot-0
var request = restHost.createRequest(“GET”, “2.0/services/securitygroup/scope/globalroot-0”); //List all the SecurityGroups
request.contentType = “application/xml”;
System.log(“Check all SecurityGroups- Request URL: ” + request.fullUrl); //Display request URL
var response = request.execute();
var SecGrouplistXML = new XML(response.contentAsString); //Convert response as String
var SecGroupList = SecGrouplistXML.securitygroup;
//System.log(SecGroupList);
var SecGroupID = [];
for each (var secgroup in SecGroupList) {
if (secgroup.name.text() == ipSetName) {
SecGroupID.push(secgroup.objectId.text().toString());
}
}
if (SecGroupID.length == null) throw(“No SecGroupID found”);
System.log(“SecurityGroup-Id found: “+SecGroupID);
//Add IpSet as Member to SecurityGroup with PUT command against
//https://nsx.rtsvl.local/api/2.0/services/securitygroup/securitygroup-31/members/ipset-12
var put = “/2.0/services/securitygroup/securitygroup-31/members/”
var request = restHost.createRequest(“PUT”, “/2.0/services/securitygroup/”+ SecGroupID +”/members/”+IpSetID);
request.contentType = “application/xml”;
request.execute();
//System.log(request);

And Last the fourth:

//This Scriptable Task GET:s an XML the ID for the SecurityPolicy called “int30 Security Policy”.
//Then modifies the XML and changes the values for the Securitygroup and the name with the ipSetName and the SecurityGroup ID.
//To update a security policy, one must first fetch it with GET first.
//You then edit the received XML and pass it back as the input with PUT. The specified configuration replaces the current configuration.
//You can retrieve a specific security policy by specifying its ID or all security policies.
//Retrieve the existing configuration of “int30 security Policy”
var request = restHost.createRequest(“GET”, “2.0/services/policy/securitypolicy/policy-6”);
request.contentType = “application/xml”;
//Execute the HTTP request
System.debug(“GET Request URL: ” + request.fullUrl);
var response = request.execute();
var secpolicydocument = XML(response.contentAsString);
System.debug(secpolicydocument.toString());
System.debug(“SecurityGroupID is now: ” + SecGroupID);
//Change the ObjectID in the SecondarySecurityGroup in the Security Policy to the ID of the SecGroupID
secpolicydocument.actionsByCategory.action.secondarySecurityGroup.objectId = SecGroupID;
secpolicydocument.actionsByCategory.action.secondarySecurityGroup.name = ipSetName;
xmlbody=secpolicydocument.toString();
System.debug(“HTTP Body being sent: ” + xmlbody);
var request = restHost.createRequest(“PUT”, “2.0/services/policy/securitypolicy/policy-6”,xmlbody);
request.contentType = “application/xml”;
var response = request.execute();

Next Up..

Create a XaaS Blueprint with the workflow in vRealize Automation and add it to our Multimachine Blueprint

In this section we want to make sure that the created workflow is run in our Multimachine Blueprint. And make sure that the workflow is run last after the VMs and Edge Loadbalancer has all been created.

First we go to vRA and go to the Design tab and select XaaS Blueprints.

We create a new XaaS Blueprint and name it: Get Edge LB VIP and add to FW SecPolicy Group.

Then we go to our Multimachine Blueprint and Edit it.

In the Blueprint we drag the XaaS on to the canvas. Here it is important to drag the bullet and create an arrow to point to the Loadbalancer. This creates a dependency so that the XaaS blueprint is run after the LB is created. To read mor about dependencies see this linkWe then save the Blueprint and next go to the catalog tab in vRA and run it.If we go into our Request and select Execution Information we see the steps being performed and when all is completed it should show success.

We can also go into our vCenter server and check the NSX Manager and Service Composer to see the modifications and creation of the machines and LB.

First we check the Securitygroup created: We see that the name of the IPSet+EdgeName is a created Securitygroup that includes the IPset.We then check the IP Sets and see that the IP Set is created with the IP of the Edge Loadbalancer VIP.Next we go into the Security Policies tab and select the int30 Security Policy
Here we see the first Firewall rule has been changed and the IPSet-Edge-MultiTierNAT-33db…. Security Group has been added to the Allow LB to RDP to VM rule.

This was it and last we can also check and do an RDP session against the LB VIP and against the VM IP to see the results.The IP address to the VM is 10.1.30.210 and the Edge LB VIP is 10.1.30.211. We first try to RDP to the VM. and see that it don’t allow RDP.Next we try RDP against the LB VIP and it works.
We also do a hostname check on the VM and see that we are in the actual VM behind the Loadbalancer.

The End. Thanx for reading…

Leave a Reply

Your email address will not be published.