Deploying from a Master Template using multiple service broker forms, using vRA API

Hello Everyone! I hope you’re having a good end of the year.

On today’s post, I will talk about a specific use case and one of the ways to solve it:

The business need was to do the following:

  • Have a single master template with dozens of inputs, to fullfill every deployment need.
  • This master template will be consumed by multiple projects and different users
  • Availability of inputs need to change based on the consumer / project
  • Visibility of inputs needs to change based on the consumer / project
  • Format of inputs needs to change based on the consumer / project
  • Source (in case of external data) for input data needs to change based on the consumer / project

You can see that we’re hitting a few limitations in the vRA OOB code:

  • The ‘conditional’ values for existence, visibility, format, etc, for a service broker form inputs don’t allow for this level of customization
  • A single cloud template can’t have more than one service broker form attached to it

So how do we solve this business need? Here comes the API solution!

Important: all the API information in swagger format (everything that was used in making this solution) is available in your vRA instance at https://VRA_FQDN/automation-ui/api-docs

API Documentation URL

What does the solution need to accomplish?

I will make a quick summary of what the code needs to do

  • Grab the inputs from a service broker form (and the requester ID, this is important)
  • Save the actual deployment name, but make the API deployment (mapped to the vRO workflow) use a temporary
  • Use the inputs to deploy the master template blueprint via the API (since we’re using the API and we don’t have access to the requester’s credentials, the API call will be executed by an administrative account configured in vRO)
  • Poll the master template blueprint deployment until it is successful
  • Once it is successful, change the owner to the original requester
  • Once that is done, destroy the temporary deployment that generates the API one.

Does that make sense?

I’ll break it down a bit:

These are the blueprint inputs:

inputs:
  instances:
    type: integer
    default: 1
  flavor:
    type: string
    default: SMALL
  image:
    type: string
    default: centos
  network:
    type: string
    default: 'network:web'
  environment:
    type: string
    default: 'env:vsphere'

These inputs (and a bit more) are the ones that are going to be used in the API call to the blueprint-request API -> part of that code. I create the body of the call with the inputs

var blueprintId = "01b5b4db-48b6-4b29-b062-a7dc1c5d9c93" // hardcoded master template
var blueprintInputs = {}
blueprintInputs.instances = instances
blueprintInputs.environment = environment
blueprintInputs.image = image
blueprintInputs.network = network
blueprintInputs.flavor = flavor
var blueprintBody = {}
blueprintBody.blueprintId = blueprintId
blueprintBody.blueprintVersion = "1"
blueprintBody.deploymentName = realDeploymentName
blueprintBody.projectId = projectId
blueprintBody.reason = "X"
blueprintBody.inputs = blueprintInputs
blueprintBodyString = JSON.stringify(blueprintBody)
System.log(blueprintBodyString)
var request = restHost.createRequest("POST", "/blueprint/api/blueprint-requests", blueprintBodyString);

Now those inputs need to be part of the action and the workflow we’re going to use, as you can see here:

vRO Action Inputs

You can see that we have some extra inputs that are not in the blueprint!

  • All the REST configuration will be variables of the workflow that is calling the action. This will use the previously configured REST host and the credentials
  • ProjectId is needed for the deployment, and we get that from the Service Broker Form
  • ownerId is needed for the deployment change owner action, and we get that from the execution context of the workflow that is being called by the service broker form
  • realDeploymentName is the actual deployment name (remember that the Service Broker form will use the temporary deployment name, and the actual deployment will use the name you input.

So what does the structure look like? In this case, we have two offerings for two projects:

Each of them have different configurations for the fields, for example:

projectId and temporary deployment name are visible fields, the rest is editable
projectId and temporary deployment name are not visible, plus, a bunch of fields aren’t editable

These two service broker forms map to two vRO workflows:

The two workflows

Why do I need two workflows? because as mentioned before, I can’t use two service broker forms for the same catalog item. However, these two vRO workflows are just wrappers of the ‘main’ workflow

The ‘offering’ workflow is just a wrapper for the base workflow

However, there is an important caveat here. The ownerId will only be part of the workflow that is called by Service Broker, in this case, the wrapper one. So the information for the requester is on the execution context of this workflow.

And I need to pass that to the base workflow. So how do I do that? By extracting the property from the execution context, and then passing it to the base workflow.

The only thing left now is to destroy the temporary deployment after it is done with the API one. So how do we do that?

We have a workflow that will delete a deployment via API – It basically calls the the deployments API with a DELETE action

//delete Deployment
System.log(deploymentId)
var request = restHost.createRequest("DELETE", "/deployment/api/deployments/"+deploymentId);
request.contentType = "application/json";
request.setHeader("accept", "application/json");
request.setHeader("Authorization", "Bearer " + tokenResponse)
 
//Attempt to execute the REST request
try {
    response = request.execute();
    jsonObject = JSON.parse(response.contentAsString);
    System.log(response.contentAsString)
}
catch (e) {
    throw "There was an error executing the REST call:" + e;
}

The deploymentId comes from the subscription run. Since this is run from the Event Broker state ‘Deployment Completed’, we have the deploymentId available there

deploymentId parameter on the event broker state

So we just extract it (the same way we did with the execution context) but from the inputProperties (payload used in the event broker subscriptions)

So how does all of this look in an actual run? Let’s show it in a video! (takes around 6 minutes, you will see the temporary deployment being generated, then the actual one via the API, the owner name change, and the destruction of the original one.

Deployment DEMO!!!

And I’m going to attach the code of the two most important actions that form the workflows (deployViaApi and deleteDeployment) here:

https://github.com/luchodelorenzi/scripts/blob/master/deleteViaAPI.js

https://github.com/luchodelorenzi/scripts/blob/master/deployViaAPI.js

Summary

I hope you enjoyed reading and understanding this as much as I did while trying to come up with this solution and then making this a reality. This idea can be heavily customized to suit other use cases (and grow this one way more) but the principles used here should still apply!

Please leave your feedback in the comments if you liked it, and share it!

One thought on “Deploying from a Master Template using multiple service broker forms, using vRA API

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s