If you’re like most large IT environments, a device naming standard is common to maintain order on your network when deploying new devices. Some IT environments utilize simple naming standards, while others are complex and might vary depending on location, device type, device usage, or some other abstract reason. vRealize Automation 8 introduced significant improvements over vRealize Automation 7 when it comes to machine naming including support for naming templates based on:
While these options likely support the majority of use cases, there are still situations where you might need to implement additional customization or verification processes to your machine name generation. In this post, I will provide a quick overview of the built-in capabilities for machine name customization, and demonstrate how you can utilize ABX functions to generate unique names as well as support verification of hostname availability.
As I mentioned above, vRealize Automation 8 introduced a flexible option for customizing the names generated for machines. Through the use of variable-based templates, you can customize how resources are named on a per-project basis. These variables can be derived from resource names, user details, randomly generated numbers, as well as custom properties assigned to resources such as the blueprint, an endpoint, or a project. So let’s walk through an example to gain a better understanding of how the vRealize Automation 8 Custom Naming Template works.
In this example, let’s assume that our corporate network naming policy requires that a hostname includes the following information:
An example of this hostname could be “PR1-WIN-WEB001”. This example naming convention uses information specific to the project and to the blueprint/server being deployed. To accomplish this, we need to define three custom properties. For this example, we will use the following:
Now that we have decided on what names we will use for custom properties, we can define our Custom Naming Template on our project. When we define a naming template, we will add each variable using the text “${object.property}”. Each property is sourced from one of 6 objects: project, endpoint, resources, user, username, random digits. In our example, we use properties defined on both the project and the resources objects. Our desired naming standard would be satisfied by the following template:
${resource.owner}-${resource.osType}-${resource.serverType}${###}
While it might seem like we should be using the “project” object for the “owner” property, we actually will reference the “resource” object as all custom properties defined in a project are passed down and added as custom properties to each resource as they are requested.
To define the template, open one of your projects within vRealize Automation 8 Cloud Assembly. Select the Infrastructure tab from the top, click Projects from the left side navigation, open the details of your project and, select the Provisioning tab.
In the Custom Naming Template field, enter the following text, then save your changes to the project:
${resource.owner}-${resource.osType}-${resource.serverType}${###}
Now that we have decided on the name of our custom properties and defined a Custom Naming Template on our project, we now need to add our custom properties to our objects. In this example, we will be adding one property to our project (“owner”), and two properties to our blueprints (“osType” and “serverType”).
First, we will tackle the easiest part and add a custom property to our project. Again, in vRealize Automation 8 Cloud Assembly, select the Infrastructure tab from the top, click Projects from the left side navigation, open the details of your project, and select the Provisioning tab. Scroll down to the section titled Custom Properties, specify a new property with the following values, then save your project:
Next, modify your blueprint to add the “os” and “serverType” properties. To accomplish this, in vRealize Automation 8 Cloud Assembly, select the Blueprints tab from the top, open one of your blueprints, select each machine in your blueprint and add the following YAML code to the resource:
properties:
osType: WIN
serverType: WEB
If your blueprint already allows for the user to select a server type, you’d instead define the “serverType” property using your input like this:
properties:
osType: WIN
serverType: '${input.serverType}'
Click the Test button to verify that your deployment works successfully. Upon a successful test deployment, select the Infrastructure tab from the top of the window, then select Requests from the left side under the Activity heading. Click the arrow next to your test deployment to see the name of the resource generated by the test. If successful, you should see an object that matches the desired naming convention.
Now that we have successfully implemented our naming standard using the built-in Custom Naming Template feature, we will look at how we can achieve a similar naming standard using ABX functions to allow for more control over our hostname customization.
There may be some situations where a naming standard can not be implemented using the built-in Custom Naming Template feature. One of those situations that I’ve frequently seen is where a naming convention includes a numeric sequence that indicates which environment the server belongs to. To demonstrate how to implement a standard like this, our new example naming standard will be the following:
Because our naming standard now dictates a specific series of numbers that our name will use based on an attribute of the server, we can no longer use the builtin Custom Naming Template variable of ${###} as we have no control over the number generated. To accomplish this new example, we will use the following custom properties:
To meet our new naming requirements, we will implement custom scripting code to generate our hostnames. Luckily, vRealize Automation provides us with the ability to subscribe to events that allow us to execute code during various lifecycle transitions within the application. In this particular case, we will use this capability to execute a custom Python-based ABX function during the “Compute allocation” stage of the provisioning lifecycle. This event triggers before the allocation of the compute resource on the endpoint.
For us to determine the numeric range to use in our hostname, our blueprint will need to provide the {environment} property so that the ABX function can decide which set of numbers to use. To accomplish this, first, add the following to the “inputs” section of your blueprint’s YAML:
environment:
type: string
enum:
- Production
- Stage
- Development
title: Server Environment
description: The target environment of server you are deploying.
Next, assign the input to a custom property on the blueprint. To accomplish this, add the following text to the “properties” section of your CloudMachine resource:
properties:
osType: WIN
serverType: '${input.serverType}'
environment: '${input.environment}'
vRealize Automation 8.0 provides us several options for implementing extensibility features. They include vRealize Orchestrator workflows, ABX flows, ABX REST requests, ABX REST polls, and ABX scripts (based on Python 3 or Node.js 6). In vRealize Automation 7, your only option for this process was through the use of vRealize Orchestrator workflows. Since ABX scripts are a new capability in vRealize Automation 8, and VMware was kind enough to include a template function for renaming our VMs, let’s use this new feature to implement our custom names.
Our first step is to create our ABX action. To accomplish this, in vRealize Automation 8 Cloud Assembly, select Extensibility from the top of the page, then select Actions from the left side under the Library section. Next, click the + NEW ACTION button to begin creating our new action.
Provide a name for our action, such as “Generate Custom Hostname” and select the project that should own the action. Click the NEXT button to move on to creating our action. On the resulting screen, select the LOAD TEMPLATE link at the top right of the scripting screen, select the Rename VM template from the list of templates, then click the LOAD button.
This script template assumes that our ABX function will be receiving a new VM name as part of our inputs, but since we will be generating our name, we can delete the “newName” input from our script. To do this, under the Inputs section on the ride side of the screen, click the minus sign beside the “newName” entry. Next, click the plus sign to add a new input. Use the following values for the new input:
Now that we’ve defined our inputs for the script, replace the script itself with the following and click the SAVE button to save the changes:
def handler(context, inputs):
"""Set a name for a machine
:param inputs
:param inputs.resourceNames: Contains the original name of the machine.
It is supplied from the event data during actual provisioning
or from user input for testing purposes.
:return The desired machine name.
"""
import random
environment\_number = 0 #variable used to store our random number
old\_name = inputs\["resourceNames"\]\[0\]
new\_name = "{0}-{1}-{2}{3}" #variable used for our new resourceName
#Determine which numeric sequence to use and then generate a random number within the correct rant
if inputs\["customProperties"\]\["environment"\] == "Production":
environment\_number = random.randrange(100,200)
elif inputs\["customProperties"\]\["environment"\] == "Stage":
environment\_number = random.randrange(200,300)
else:
environment\_number = random.randrange(300,400)
#Using the string.format function to piece together our new resourceName. Notice the ".zfill(3)" which is used to ensure our number is 3 digits in length just incase our number sequence started at 0 instead of 100
new\_name = new\_name.format(inputs\["customProperties"\]\["owner"\], inputs\["customProperties"\]\["osType"\], inputs\["customProperties"\]\["serverType"\], str(environment\_number).zfill(3))
#Assign our new resourceNames output
outputs = {}
outputs\["resourceNames"\] = inputs\["resourceNames"\]
outputs\["resourceNames"\]\[0\] = new\_name
print("Setting machine name from {0} to {1}".format(old\_name, new\_name))
return outputs
Within the script, we accomplish the following:
The final step in implementing our new custom ABX action is to create the event subscription that will execute our action every time a compute resource reaches the “Compute allocation” lifecycle stage. To accomplish this, within vRealize Automation 8 Cloud Assembly, click on Extensibility from the top of the screen, then select Subscriptions from the left side. Click the + NEW SUBSCRIPTION button.
Provide a name for the subscription such as “Resource Name Customization on Compute Allocation”. For the Event Topic field, click on the + ADD button, select the “Compute allocation” event from the list of event topics, then click the SELECT button. Next, for the Runnable Item field, click the + ADD button, select the ABX action that you created, then click the SELECT button. Next, ensure that you enable the Blocking option so that Cloud Assembly won’t move forward until the new name is generated. For the Recovery runnable item, select your ABX action again. Finally, click the CREATE button to create our new event subscription.
To verify that our new hostname customization event works as expected, go back and open the blueprint that you customized with the three custom properties. Click on the TEST button and fill in the required fields and click the TEST button to submit the text. Next, at the top of the screen, click on Extensibility, then select Action Runs from the left side under the Activity header. In the list of Action Runs, find the action’s run from your blueprint test. Click on the name of the action in the list to load the details of the action’s run.
On the right side of the screen, select the Log tab to see the log from your action’s run. It will list the original name and new name that the ABX script generated for your machine. As you can see, the original name matches the Custom Naming Template we defined earlier, and the new name matches the name generated by the ABX script.
The ability to write scripts in Python provides a lot of powerful options for customizing your hostnames as well as the ability to reach out to IPAM REST interfaces to verify availability or to execute NSLOOKUP queries using the Python 3 “socket” module.
Does your environment have a complex naming standard that can’t be supported out of the box? If so, I’d love to hear about it. Leave a comment below, letting me know how you have implemented it in the past or plan to implement it going forward.
Search
Get Notified of Future Posts
Recent Posts