NSX

NSX-T Deployment Automation – Part 2

Introduction:

This post is a continuation of my experimentation with NSX-T deployment automation, working on a method to quickly deploy typical network topologies for repro and testing. In the first post of this series, we used cURL and JQ to collect NSX-T UUIDs and deploy a new Tier-0 gateway. Now we will look at the steps required to implement a fully functional lab configuration consisting of Tier-0, Tier-1, Segments, DNS, and BGP.

Desired Lab Topology to test NSX-T Deployment Automation

The following lab topology covers a variety of test scenarios. The goal is to use NSX-T Deployment Automation to deploy this setup.

NSX-T Deployment Automation

Define site-specific variables

Let’s start by defining some site-specific variables that should help simplify cURL command syntax, and to make the script more generic. We will add these to a Linux shell executable file named “nsx-t-automation.sh”, and will echo them back as a reminder when running the script.

echo "Define site specific variables:"

nsxtpasswd='VMware1!VMware1!'
echo "NSX-T admin password: $nsxtpasswd"

nsxtvip="nsxtmgr.core.hypervizor.com"
echo "NSX-T FQDN: $nsxtvip"

Collect required site-specific UUIDs

Some UUIDs are required for the creation of the topology, such as transport zone and edge cluster UUIDs, and are collected using cIRL and JQ. There are some assumptions made in this example, that transport zones and an edge cluster exist. Keep in mind that these could have been created as part of the automation process, and that this example is for illustrative purposes.

 echo ""
 echo "Collect site specific IDs:"

 overlay_transport_zone_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/policy/api/v1/infra/sites/default/enforcement-points/default/transport-zones" | jq -r '.results[0].id')
 echo "Overlay Transport Zone ID: $overlay_transport_zone_id"

 vlan_transport_zone_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/policy/api/v1/infra/sites/default/enforcement-points/default/transport-zones" | jq -r '.results[1].id')
 echo "VLAN Transport Zone ID: $vlan_transport_zone_id"

 edge_cluster_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[].id')
 echo "Edge Cluster ID: $edge_cluster_id"

 edge_node_0=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[0].members[0].transport_node_id')
 echo "Edge Node 0: $edge_node_0"

 edge_node_1=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[0].members[1].transport_node_id')
 echo "Edge Node 1: $edge_node_1"

Step 1: Create an External Segment

We will add an external segment using the UI, and then use curl to review the resulting configuration in JSON format. This is a good approach as you get more familiar with the NSX-T REST API.

Notice that to create the external segment, the following parameters are required:

  • Segment Name
  • Transport Zone
  • VLAN
NSX-T Deployment Automation

Use curl to review the resulting configuration in JSON format.

curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/policy/api/v1/infra/segments" | jq '.'

Once again, notice that to create the external segment, the following parameters are required:

  • Segment Name: external-segment
  • Transport Zone: 80a2b6a0-d2d1-4b0a-a42e-7dcb9a6f2d62: $vlan_transport_zone_id was collected earlier
  • VLAN: 0

Also notice that some sections, such as advanced_config are default and optional, so they don’t need to be specified in the creation of the external segment.

Here is the resulting cURL command to create the external segment, where we use $vlan_transport_zone_id collected earlier, and the three required parameters:

echo "Step 1: Create External Segment"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"type": "DISCONNECTED","vlan_ids": ["0"],"transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/'"$vlan_transport_zone_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/segments/external-segment"

external_segment_id=$(curl --silent  -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/segments/external-segment" | jq -r '.id')
echo "External segment id: $external_segment_id" 

PUT or PATCH, that is the question:

Notice that in the creation of the external segment we used the PATCH command. This could also have been performed using a PUT. The PATCH and PUT can both be used to create or update a segment, expect that PUT has some additional overhead, where the “_revision” property must be specified. In order to prevent one client from overwriting another client’s updates, NSX-T employs a technique called optimistic concurrency control. In the sample NSX-T automation script for the lab environment, we are not concerned with multiple REST API clients, so a more simple PATCH will suffice.


Step 2: Create Tier-0 Gateway

Now that we ‘ve established an approach in creating an object in detail, we will continue to add NSX-T objects.

echo "Step 2: Create Tier-0 Gateway"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"transit_subnets": ["100.64.0.0/16"],"internal_transit_subnets": ["169.254.0.0/24"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0"


Step 3: Instantiate Tier-0 on Edge Cluster, and configure route redistribution

echo "Step 3: Instantiate Tier-0 on Edge Cluster, and configure route redistribution"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"route_redistribution_types": [ "TIER1_CONNECTED", "TIER0_CONNECTED" ],"edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default"


Step 4: Add two uplink interfaces to Tier-0

echo "Step 4: Add two uplink interfaces to Tier-0"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'/edge-nodes/'"$edge_node_1"'","segment_path": "/infra/segments/external-segment","type": "EXTERNAL","subnets": [ {"ip_addresses": ["192.168.100.102"],"prefix_len": 24}]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink1"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'/edge-nodes/'"$edge_node_0"'","segment_path": "/infra/segments/external-segment","type": "EXTERNAL","subnets": [ {"ip_addresses": ["192.168.100.103"],"prefix_len": 24}]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink2"


Step 5: Change Tier-0 BGP AS

echo "Step 5: Change Tier-0 BGP AS"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"local_as_num": "65111"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp"


Step 6: Add BGP Peer

echo "Step 6: Add BGP Peer"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"neighbor_address": "192.168.100.2","remote_as_num": "65100","out_route_filters": ["/infra/tier-0s/lab-tier-0/prefix-lists/prefixlist-out-default"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp/neighbors/peer1"


Step 7: Create DHCP Server

echo "Step 7: Create DHCP Server"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"server_address": "192.168.60.1/24","edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'","lease_time": 86400}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/dhcp-server-configs/DHCP_Server"


Step 8: Create Tier-1 Gateway, and configure route redistribution

echo "Step 8: Create Tier-1 Gateway, and configure route redistribution"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"tier0_path": "/infra/tier-0s/lab-tier-0","failover_mode": "NON_PREEMPTIVE","enable_standby_relocation": false,"dhcp_config_paths": ["/infra/dhcp-server-configs/DHCP_Server"],"route_advertisement_types": ["TIER1_CONNECTED","TIER1_IPSEC_LOCAL_ENDPOINT"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1"


Step 9: Instantiate Tier-1 in Edge Cluster

echo "Step 9: Instantiate Tier-1 in Edge Cluster"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1/locale-services/default"


Step 10: Add Tier-1 Segment

echo "Step 10: Add Tier-1 Segment"

curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"type": "ROUTED","subnets": [{"gateway_address": "192.168.70.1/24","dhcp_ranges": ["192.168.70.100-192.168.70.199"], "network": "192.168.70.0/24"}],"connectivity_path": "/infra/tier-1s/lab-tier-1","transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/'"$overlay_transport_zone_id"'"}}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/segments/seg1"

echo "All Done!"
 echo ""

Putting it all together, the completed Linux shell executable

I’ve added a GET after each PATCH command to verify on each step that the object was successfully completed.

 echo ""
 echo "This script tested on NSX-T 2.5.0 and 2.5.1"
 echo "Define site specific variables:"
 nsxtpasswd='VMware1!VMware1!'
 echo "NSX-T admin password: $nsxtpasswd"
 nsxtvip="nsxtmgr.core.hypervizor.com"
 echo "NSX-T FQDN: $nsxtvip"
 echo ""

 echo "Collect site specific IDs:"
 overlay_transport_zone_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/policy/api/v1/infra/sites/default/enforcement-points/default/transport-zones" | jq -r '.results[0].id')
 echo "Overlay Transport Zone ID: $overlay_transport_zone_id"
 vlan_transport_zone_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/policy/api/v1/infra/sites/default/enforcement-points/default/transport-zones" | jq -r '.results[1].id')
 echo "VLAN Transport Zone ID: $vlan_transport_zone_id"
 edge_cluster_id=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[].id')
 echo "Edge Cluster ID: $edge_cluster_id"
 edge_node_0=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[0].members[0].transport_node_id')
 echo "Edge Node 0: $edge_node_0"
 edge_node_1=$(curl --silent -k -u admin:$nsxtpasswd -X GET "https://$nsxtvip/api/v1/edge-clusters" | jq -r '.results[0].members[1].transport_node_id')
 echo "Edge Node 1: $edge_node_1"
 echo ""

 echo "Step 1: Create External Segment"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"type": "DISCONNECTED","vlan_ids": ["0"],"transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/'"$vlan_transport_zone_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/segments/external-segment"
 external_segment_id=$(curl --silent  -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/segments/external-segment" | jq -r '.id')
 echo "External segment ID: $external_segment_id"
 echo ""
 echo "Step 2: Create Tier-0 Gateway"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"transit_subnets": ["100.64.0.0/16"],"internal_transit_subnets": ["169.254.0.0/24"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0"
 tier_0_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0" | jq -r '.id')
 echo "Tier-0 ID: $tier_0_id"
 echo ""

 echo "Step 3: Instantiate Tier-0 on Edge Cluster, and configure route redistribution"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"route_redistribution_types": [ "TIER1_CONNECTED", "TIER0_CONNECTED" ],"edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default"
 tier_0_clutser_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default" | jq -r '.edge_cluster_path')
 echo "Tier-0 Cluster ID: $tier_0_clutser_id"
 echo ""

 echo "Step 4: Add two uplink interfaces to Tier-0"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'/edge-nodes/'"$edge_node_1"'","segment_path": "/infra/segments/external-segment","type": "EXTERNAL","subnets": [ {"ip_addresses": ["192.168.100.102"],"prefix_len": 24}]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink1"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'/edge-nodes/'"$edge_node_0"'","segment_path": "/infra/segments/external-segment","type": "EXTERNAL","subnets": [ {"ip_addresses": ["192.168.100.103"],"prefix_len": 24}]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink2"
 external_uplink1_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink1" | jq -r '.id')
 echo "External Uplink1 ID: $external_uplink1_id"
 external_uplink2_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/interfaces/external-uplink2" | jq -r '.id')
 echo "External Uplink2 ID: $external_uplink2_id"
 echo ""

 echo "Step 5: Change Tier-0 BGP AS"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"local_as_num": "65111"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp"
 BGP_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp" | jq -r '.id')
 echo "BGP ID: $BGP_id"
 echo ""

 echo "Step 6: Add BGP Peer"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"neighbor_address": "192.168.100.2","remote_as_num": "65100","out_route_filters": ["/infra/tier-0s/lab-tier-0/prefix-lists/prefixlist-out-default"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp/neighbors/peer1"
 BGP_peer_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-0s/lab-tier-0/locale-services/default/bgp/neighbors/peer1" | jq -r '.id')
 echo "BGP Peer ID: $BGP_peer_id"
 echo ""

 echo "Step 7: Create DHCP Server"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"server_address": "192.168.60.1/24","edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'","lease_time": 86400}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/dhcp-server-configs/DHCP_Server"
 dhcp_server_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/dhcp-server-configs/DHCP_Server"| jq -r '.id')
 echo "DHCP Server ID: $dhcp_server_id"
 echo ""

 echo "Step 8: Create Tier-1 Gateway, and configure route redistribution"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"tier0_path": "/infra/tier-0s/lab-tier-0","failover_mode": "NON_PREEMPTIVE","enable_standby_relocation": false,"dhcp_config_paths": ["/infra/dhcp-server-configs/DHCP_Server"],"route_advertisement_types": ["TIER1_CONNECTED","TIER1_IPSEC_LOCAL_ENDPOINT"]}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1"
 tier_1_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1" | jq -r '.id')
 echo "Tier-1 ID: $tier_1_id"
 echo ""

 echo "Step 9: Instantiate Tier-1 in Edge Cluster"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"edge_cluster_path": "/infra/sites/default/enforcement-points/default/edge-clusters/'"$edge_cluster_id"'"}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1/locale-services/default"
 tier_1_clutser_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/tier-1s/lab-tier-1/locale-services/default" | jq -r '.edge_cluster_path')
 echo "Tier-1 Cluster ID: $tier_1_clutser_id"
 echo ""

echo "Step 10: Add Tier-1 Segment"
 curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -d '{"type": "ROUTED","subnets": [{"gateway_address": "192.168.70.1/24","dhcp_ranges": ["192.168.70.100-192.168.70.199"], "network": "192.168.70.0/24"}],"connectivity_path": "/infra/tier-1s/lab-tier-1","transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/'"$overlay_transport_zone_id"'"}}' -X PATCH "https://$nsxtvip/policy/api/v1/infra/segments/seg1"
 tier1_segment_id=$(curl --silent -k -u admin:$nsxtpasswd -H "Content-Type: application/json" -X GET "https://$nsxtvip/policy/api/v1/infra/segments/seg1"| jq -r '.id')
 echo "Tier-1 Segment ID: $tier1_segment_id"
 echo ""

 echo "All Done!"
 echo ""

Running the completed Linux shell executable

We are starting without any networking objects:

Add execute permissions to the Linux shell executable:

chmod +x nsx-t-automation.sh

Run the Linux shell executable

./nsx-t-automation.sh

 This script tested on NSX-T 2.5.0 and 2.5.1
 Define site specific variables:
 NSX-T admin password: VMware1!VMware1!
 NSX-T FQDN: nsxtmgr.core.hypervizor.com

 Collect site specific IDs:
 Overlay Transport Zone ID: 68b56dac-09ac-4155-af2e-7f43419cbf0f
 VLAN Transport Zone ID: d325d53e-eab6-4afe-953d-5d87637cc98a
 Edge Cluster ID: 6d73abe2-8233-4d76-9290-6bd66999b198
 Edge Node 0: d1de934a-0968-11ea-af85-0050569657e0
 Edge Node 1: 0d249652-0969-11ea-b387-00505696c478

 Step 1: Create External Segment
 External segment ID: external-segment

 Step 2: Create Tier-0 Gateway
 Tier-0 ID: lab-tier-0

 Step 3: Instantiate Tier-0 on Edge Cluster, and configure route redistribution
 Tier-0 Cluster ID: /infra/sites/default/enforcement-points/default/edge-clusters/6d73abe2-8233-4d76-9290-6bd66999b198

 Step 4: Add two uplink interfaces to Tier-0
 External Uplink1 ID: external-uplink1
 External Uplink2 ID: external-uplink2

 Step 5: Change Tier-0 BGP AS
 BGP ID: bgp

 Step 6: Add BGP Peer
 BGP Peer ID: peer1

 Step 7: Create DHCP Server
 DHCP Server ID: DHCP_Server

 Step 8: Create Tier-1 Gateway, and configure route redistribution
 Tier-1 ID: lab-tier-1

 Step 9: Instantiate Tier-1 in Edge Cluster
 Tier-1 Cluster ID: /infra/sites/default/enforcement-points/default/edge-clusters/6d73abe2-8233-4d76-9290-6bd66999b198

 Step 10: Add Tier-1 Segment
 Tier-1 Segment ID: seg1

All Done!

After running the NSX-T automation script, the basic topology has been successfully deployed:

NSX-T Deployment Automation

Upcoming in NSX-T Deployment Automation – Part 3

This completes Part 2 of NSX-T Deployment Automation, the steps required to implement a fully functional lab configuration consisting of Tier-0, Tier-1, Segments, DNS, and BGP. In the future, we will look at tieing similar steps together with an Ansible Playbook.

Begin typing your search term above and press enter to search. Press ESC to cancel.