/ AUTOMATION

IPAM Integration with VMware Cloud Assembly

Back again to look at IPAM integration with VMware Cloud Assembly, part of Cloud Automation Services. I wanted to look at IPAM integration for externally managed static IP assignment, and/or DNS management, as this is one of the more commonly seen integration requirements for enterprise customers. Today this integration requires extensibility, in this case, we will use vRealize Orchestrator to integrate.

I will use Infoblox IPAM to demonstrate VMware Cloud Assembly extensibility with one of the more commonly used IPAM solutions, the choice is simply down what we have deployed in our lab, but really you could interchange this with any competing IPAM solution and achieve the same outcome.

If your interested in extensibility and haven’t seen the original posts on extending Cloud Assembly to integrate with ServiceNow these articles are probably a good primer to get started with Cloud Assembly extensibility in general.

Overview

Using Cloud Assembly extensibility at the network configure state each selected network is passed thru to the payload (inputProperties), and then we can query of the networkSelectionIds against the Cloud Automation Services API to obtain the network details and then use this to get the next available IP address and register host record via the Infoblox REST API.

In this scenario, we use Cloud Assembly’s native tag based placement logic to select suitable networks based on blueprint constraints matched to network capabilities. We are able to take advantage of Cloud Assembly for placement of the suitable networks, then validate sufficient IP capacity against Infoblox API, if there are no IPs available we move to the next suitable network provided by Cloud Assembly in the payload. Once we have a network with capacity and IP supplied by the IPAM our reserved IP is passed back to Cloud Assembly via outputs using the addresses object containing the assigned IP and this is then passed into the VM and used for static assignment which has been specified on our blueprint, we also pass back the selected network using networkSelectionIds object.

Tag Based Placement

Our blueprint will use three constraint tags platform:vsphere, environment:test, region:sydney the tag-based placement function of the Cloud Assembly provisioning engine will match these constraint tags against the capability tags we have associated to resources in Cloud Assembly to down select suitable resources for placing the provisioned instance.

IPAM Blueprint

Below is our example blueprint for integrating with IPAM, the key pieces here are we have specified the network with an assignment: static and we have defined a new custom property enable_infoblox: 'true' which allows us to filter our event subscription, allowing for our IPAM integration to be optionally enabled.

Example IPAM Blueprint YAML

formatVersion: 1
inputs:
  hostname:
    type: string
  dnsDomain:
    type: string
    default: test.cmlab.local
    readOnly: true
  enableDNS:
    title: Enable IPAM DNS Integration
    type: boolean
resources:
  Cloud_Machine_1:
    type: Cloud.Machine
    properties:
      image: centos 7
      flavor: small
      name: '${input.hostname}'
      constraints:
        - tag: 'platform:vsphere'
        - tag: 'region:sydney'
      enable_infoblox: 'true'
      assignedHostname: '${to_lower(input.hostname) + ''.'' + to_lower(input.dnsDomain)}'
      enableDNS: '${input.enableDNS}'
      cloudConfig: |
        #cloud-config
        preserve_hostname: false
        hostname: '${input.hostname}'
      networks:
        - name: '${resource.Cloud_NSX_Network_1.name}'
          assignment: static
  Cloud_NSX_Network_1:
    type: Cloud.NSX.Network
    properties:
      name: mgmt
      networkType: existing
      constraints:
        - tag: 'environment:test'
        - tag: 'region:sydney'

Extensibility

To integrate with IPAM we will use the network configure state, this subscription needs to be configured as blocking to allow for output updates. This event subscription will be conditionally executed based on the below property filter based on blueprint properties.

event.data.customProperties[‘enable_infoblox’] == “true”

Infoblox IPAM subscription

Network Configure Payload

The payload for the network configure event schema is passed to vRealize Orchestrator as inputProperties object to the workflow.

The key items we will use from the payload below, are the networkSelectionIds each networkSelectionId is a suitable network based on tag placement, from an API perspective this equates to /iaas/api/fabric-networks/{networkSelectionId} from this API we are able to obtain the network CIDR details and use these as a key for subsequent API calls to our IPAM.

Example Network Configure Payload (inputProperties)

{
	"componentId": "Cloud_Machine_1",
	"endpointId": "16e7c9e5ab722475-7f703c5265a63d87-a9fa4c182a55f2e5a346096d24a012e642b990229d7d1d6d48f09ff30c04dbb0-9160b8b38915f07557a982a8b5fa5",
	"externalIds": [
		"cloudbrokers-mcm389828-105026536448"
	],
	"blueprintId": "34d49b3f-1757-477e-9ac7-cb19637aa895",
	"tags": {},
	"customProperties": {
		"image": "centos 7",
		"assignedHostname": "cloudbrokers.test.cmlab.local",
		"mytags": "[{\"key\": \"foo\", \"value\": \"bar\"}]",
		"othertags": "[{\"foo\":\"bar\"}]",
		"enable_infoblox": "true",
		"delete": "false"
	},
	"networkProfileIds": [
		"fdd11ae865d6367557a991d4e8398"
	],
	"componentTypeId": "Cloud.Machine",
	"requestId": "eb620c1f-2520-4799-87b1-c06a95999ade",
	"deploymentId": "eb620c1f-2520-4799-87b1-c06a95999ade",
	"zoneId": "239c1ec61bfc787557a986b662438",
	"projectId": "d329cc1d-d289-4aef-a6fc-f87a1296d17e",
	"networkSelectionIds": [
		[
			[
				"e86389d25568947557a982bb28a21",
				"18d355310daa6c7557a982bb729b8"
			]
		]
	],
	"resourceIds": [
		"73fc0c217c6489d7"
	]
}

vRO Workflow

The key pieces of the workflow to integrate Cloud Automation Services and IPAM are outlined below.

Network Configure - IPAM

Infoblox Allocate

At the network configure state we have a generic workflow parse the payload and populate a JSON object with the VM details and all suitable networks, this data is populated via REST calls to Cloud Assembly. We then use this to make calls to Infoblox API to lookup the networks based on the CIDR details from Cloud Assembly and provided there is sufficient capacity we allocate an IP and host record in the first suitable network, DNS integration is enabled based on the blueprint inputs.

Get CAS Details

//get REST Host from configuration element (configPath, configName,attributeName)
var restHost = System.getModule("au.com.cs.config").getRestHostFromConfig("CS","environmentConfig","CASRestHost")
var tokenResponse = System.getModule("au.com.cs.cas").casLogin("CS", "environmentConfig", restHost)
var bearer = "Bearer " + tokenResponse;

//Get machine details for each resource
var casMachines = [];

var resourceIds = inputProperties['resourceIds']
for(var i = 0 ; i < resourceIds.length ; i++ ) {

	System.log("Resource Id: " + resourceIds[i])
	var urlTemplate = "/iaas/machines/" + resourceIds[i];
	var machine = System.getModule("au.com.cs.rest").request(restHost,"machineDetails","GET",urlTemplate,null,null,bearer)
	casMachines.push(JSON.parse(machine));
}

//Get Fabric Networks for each network
var casNetworks = [];

networkSelectionIds = inputProperties['networkSelectionIds'][0][0]
for(var i = 0 ; i < networkSelectionIds.length ; i++ ) {

	var urlTemplate = "/iaas/api/fabric-networks/" + networkSelectionIds[i];
	var network = System.getModule("au.com.cs.rest").request(restHost,"networkDetails","GET",urlTemplate,null,null,bearer)
	casNetworks.push(JSON.parse(network));
}

System.log(JSON.stringify(casMachines,null,2));
System.log(JSON.stringify(casNetworks,null,2));

machines = JSON.stringify(casMachines,null,2)
networks = JSON.stringify(casNetworks,null,2)

Our allocated IP address and selected network, along with a unique IPAM reference are passed as outputs to update the associate the IP with the instance and down select our selected network. In this scenario, we have assumed a single interface is used per instance.

Compute Removal - IPAM

On the compute post removal event, we delete the IP and host record from the IPAM, in this case using a unique IPAM reference which we have stored as the custom property ‘ipamRef’, this allows us to delete the record from Infoblox API without the need for additional queries.

Infoblox release

Deploying our IPAM example Blueprint

As an example we have allowed for the hostname to be user entered with DNS integration enabled/disabled via a boolean, this checkbox controls the Infoblox API parameters to allow infoblox to manage DNS, otherwise, we just use our IPAM for IP management

After successful deployment, our statically assigned IP address from Infoblox can be seen in Cloud Assembly.

Our IPAM record successfully created in Infoblox.