NSX Tagging
Applying NSX Tags with Python
2025-09-16
We use tags to generate dynamic groups in NSX and then target these groups in our distributed firewall rules. Tagging was a manual process when we brought NSX into our environment. Sometimes we'd forget about it and spend time troubleshooting connectivity issues before realizing we never tagged the system. We needed a way to apply tags during our provisioning process.
To accomplish this, requesters are prompted to select one or more tags when initiating a new system build. Selected tags are stored as parameters in the JSON data associated with the build, and then passed into a script by Ansible during the build process. The script assumes an nsx.json
file is present with the following attributes:
{
"nsx_host": "nsx.domain.com",
"nsx_user": "nsxadmin",
"nsx_pass": "supersecret"
}
The script takes a single tag and vm name. The vm name needs to match the NSX entry exactly.
#!/bin/python3
import requests
import json
import os
import sys
import argparse
from os.path import dirname,abspath
import urllib3
# Disable certificate warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
try:
config_file_path = os.path.join(dirname(dirname(abspath(__file__))),"nsx.json")
config = json.load(open(config_file_path))
except Exception as e:
print(f"Failed to load config file from {config_file_path}.\r\nException: {e}")
sys.exit(1)
# NSX-T Manager configuration
nsx_manager = f"https://{config['nsx_host']}"
username = config['nsx_user']
password = config['nsx_pass']
# Get the virtual machine ID by name
def get_vm_id_by_name(vm_name):
vm_url = f"{nsx_manager}/api/v1/fabric/virtual-machines"
headers = {
"Accept": "application/json",
}
response = requests.get(vm_url, headers=headers, auth=(username,password), verify=False)
if response.status_code == 200:
vms = response.json()["results"]
for vm in vms:
if vm["display_name"].lower() == vm_name.lower():
return vm["external_id"]
raise Exception(f"Virtual machine '{vm_name}' not found.")
else:
raise Exception(f"Failed to retrieve virtual machines. Status code: {response.status_code}. Text: {response.text}")
# Function to add tags to a virtual machine
def add_tag_to_vm(vm_name, tag):
try:
vm_id = get_vm_id_by_name(vm_name)
except Exception as e:
raise e
vm_url = f"{nsx_manager}/api/v1/fabric/virtual-machines/?action=add_tags"
headers = {
"Accept": "application/json",
}
body={
"external_id": vm_id,
"tags":[tag]
}
response = requests.post(vm_url, auth=(username,password), verify=False, headers=headers, json=body)
if response.status_code == 204:
return True
else:
raise Exception(f"Failed to retrieve virtual machine details. Status code: {response.status_code}. Text: {response.text}")
def main(args):
# Add tag. On NSX-T 3.2+, the scope cannot be None. It has to be an empty string
try:
tag = {
"scope": "",
"tag": args.tag
}
if add_tag_to_vm(args.vm_name, tag):
print(f'Added {args.tag} to {args.vm_name}')
sys.exit(0)
else:
sys.exit(1)
except Exception as e:
print(f"Failed to add {args.tag} to {args.vm_name}. Exception: {e}")
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add a tag to a virtual machine in NSX-T")
parser.add_argument("-v","--vm_name", type=str, help="Name of the virtual machine", required=True)
parser.add_argument("-t", "--tag", type=str, help="Tag to add to the virtual machine", required=True)
args = parser.parse_args()
main(args)
Example
python3 nsx_add_tags.py --vm-name webserver1 --tag http