Recently, I was asked by a customer to deploy a custom NSX-T firewalling solution for their virtual machines, where virtual machines owned by an Aria Automation user are allowed to communicate with virtual machines of the same user. The solution leverages NSX-T firewall rules based on groups, where the group membership is defined based on NSX-T tags attached to a virtual machine.

To achieve the custom tagging of virtual machines in NSX-T during the VM deployment phase in Aria Automation, I developed a Orchestrator workflow leveraging the capabilities of the NSX-T API.

In this blog post, I’ll demonstrate how to use the NSX-T API from Orchestrator.

NSX-T provides a programmatic API to automate management activities. The API follows a resource-oriented Representational State Transfer (REST) architecture, using JSON object encoding. Clients interact with the API using RESTful web service calls over the HTTPS protocol.

Each API method is identified by a request method and URI. Method parameters are specified as key-value pairs appended to the URI. Unless otherwise noted, request and response bodies are encoded using JSON, and must conform to the JSON schema associated with each method. The content type of each request and reply is “application/json” unless otherwise specified. Each request that can be made is documented in the API Methods section. The associated request and response body schemas are documented in the API Schemas section.

Most API calls require authentication. The NSX-T API supports several different authentication schemes, like HTTP Basic Authentication or Session-Based Authentication.

You can find more information about the NSX-T REST API in the official API reference.

To make the authentication handling easier in Orchestrator, we can leverage the REST plugin by adding the NSX Manager as a REST host endpoint with all required authentication data preconfigured.

Add the REST host in Orchestrator

The procedure for this is to run the a workflow to add a REST host and configure the host connection parameters:

  1. In Orchestrator, navigate to Library > Workflows and enter the rest and host tags in the workflow search box.
  2. Locate the Add a REST host workflow and click Run.
  3. On the Host Properties tab, enter the following information (using my lab environment as example)
    • Name: nsx1a.corp.local
    • URL: https://nsx1a.corp.local/policy/api/v1/
    • Connection timeout (seconds): 30
    • Operation timeout (seconds): 60
    • Redirect strategy: defaultRedirect
  4. On the Host Authentication tab, enter the following information:
    • Host’s authentication type: Basic
  5. On the User credentials tab, enter the following information:
    • Session Mode: Shared Session
    • Authentication user name: admin
    • Authentication password
  6. On the SSL tab, enter the following information:
    • Verify whether the target hostname matches the name stored inside the server’s X.509 certificate: no
  7. Click Run.

After the workflow runs successfully, the REST host appears in the Inventory view of Orchestrator.

Create Orchestrator actions to consume the NSX REST API

First, we create an action to get a REST endpoint from the Orchestrator inventory, e.g. an action called getRestEndpoint in module local.corp.vco:

var restHost = null;
for each (restHostFinder in RESTHostManager.getHosts()) {
    var host = RESTHostManager.getHost(restHostFinder);
    if (host.name === restEndpointName) {
        restHost = host;
        break;
    }
}

if (restHost == null)
    throw "REST host with name " + restEndpointName + "not found";

return restHost;

The action has one input:

  • Input: restEndpointName
    • Type: string

The action has a return type of REST:RESTHost.

Second, we create an action to execute the actual REST calls, e.g. an action called executeRestCall in module local.corp.rest:

var host = System.getModule("local.corp.vco").getRestEndpoint(host);
var request = host.createRequest(method, pathUri, content);
request.setHeader("Accept", "application/json");  
request.setHeader("Content-Type", "application/json");
System.debug(method + "-->" + pathUri + " (" + content + ")");
var response = request.execute();
System.debug(response.statusCode);
if (response.statusCode > 299) 
    throw "HTTP error " + response.statusCode + " - " + response.contentAsString;
return response.contentAsString;

The action has the following inputs:

  • Input: method
    • Type: string
  • Input: input
    • Type: string
  • Input: pathUri
    • Type: string
  • Input: content
    • Type: string
  • Input: host
    • Type: string

The action has a return type of string.

Create a workflow to attach a NSX tag to a VM

To actually attach a NSX tag to a virtual machine, we must use a POST request to /fabric/virtual-machines with the update_tags action (see the API docs). In our simple example, we will attach a tag with the name of the requesting user in Aria Automation with a scope called “requestor“.

We create a workflow in Orchestrator called “Attach NSX tag to VM“:

var nsxManagerName = "nsx1a.corp.local";
var vmId = inputProperties.get("externalIds")[0];
if (!vmId) throw "No vm id found in externalIds"
System.debug("Got vm id: " + vmId);

var tagNameVmRequestor = System.getContext().getParameter("__metadata_userName");
System.debug("Got deployment requestor: " + tagNameVmRequestor);

const requestBody = {
	external_id: vmId,
	tags: [
        {
	 		scope: "requestor",
			tag: tagNameVmRequestor
		}
	]
};

var response = System.getModule("local.corp.rest").executeRestCall("POST", "", "/fabric/virtual-machines?action=update_tags", JSON.stringify(requestBody), nsxManagerName);
if (response === "") System.log("VM successfully tagged"); // POST returns HTTP 204 with no content

The workflow has the following inputs:

  • Input: inputProperties
    • Type: Properties

Note: the inputProperties input will be populated by Aria Automation when the corresponding extensibility subscription will be triggered. See my blog post about Aria Automation Lifecycle Extensibility for more information.

Create the Extensibility subscription in Cloud Assembly

Extensibility subscriptions allow us to extend our applications by triggering workflows or actions at specific life-cycle events.

To trigger our workflow every time a Aria Automation deployment is triggered, we create an extensibility subscription for the compute post provision lifecycle phase.

In Aria Automation Cloud Assembly, navigate to Extensibility > Subscriptions. Click New Subscription, and enter the details of the subscription:

  • Name: Attach NSX tag to VM
  • Status: Enable subscription (yes)
  • Event Topic: Compute post provision
  • Action/workflow: Attach NSX tag to VM
  • Blocking: Block execution of events in topic (yes)

Note with the above created trigger condition, the subscription will be run for every deployment. To limit it to a given cloud template, we could use a “event.data.blueprintId” condition which specifies the corresponding Cloud template Id (must be a template with a virtual machine resource type in it).

Test

In my lab, I’m now deploying a virtual machine from a given Cloud Template, e.g. as user configadmin. Once the deployment has been completed successfully, we have a VM called, e.g. Cloud_VM_1-mcm33-238257848649. We can now check in NSX Manager if the NSX tag has been applied to the VM.

In NSX Manager, navigate to Inventory > Tags and filter for the Scope “requestor” and the Tag “configadmin“:

The tag has been created and assigned to the correct VM: