In this post we will configure our second NSX-T site, the also imaginatively named, Site B.
This post is part 3 of a multipart series. Find the other parts here:
As a reminder, in this series we will be building the following lab:
(Click image to zoom in)
The build of Site B will mirror that of Site A.
Therefore, rather than creating another huge post with the same screenshots, lets make this a Too Lazy,Didn’t Read (TL,DR) and a “How to deploy with automation” all in one post.
That way, should you, I, anyone need to be reminded the steps, or indeed the order of the steps to build an NSX-T site, this post will come in handy. It will save time not having to leaf through pages of screenshots and explanation. It will also come in handy for someone looking to complete an automated deployment of an NSX-T site. The PowerShell NSX-T API calls below can be leveraged to build any size deployment.
As covered in part 1 Lab Setup and Overview , the following are required prior to an NSX-T deployment at a site:
vSphere Pre-Requisites
vSphere 7.0 or later deployed
vSphere 7.0 or later distributed switches in use
Compute Hosts Clustered
Networking Pre-Requisites
MTU equal or greater than 1700 in use everywhere
VLANS assigned for:
Management Traffic
Transport End Points (TEPS)
Uplinks
Remote Transport End Points (RTEPS)
The TL,DR Deployment
To Lazy, Didn’t Read? Simply complete the following:
Deploy NSX-T OVA and create NSX-T local manager cluster
Licence
Create Transport Zones
Create Host Uplink Profile
Create Edge Uplink Profile
Create TEP Pool
Attach vCenter
Create Transport Node Profile
Prepare Cluster
Check Host TEP Connectivity
Create Trunk VLAN Segment
Create Edge Node(s)
Check Edge TEP Connectivity
Create Edge Cluster
Once the above steps are complete, you are ready to federate!
The Automated Deployment Using NSX-T API and PowerShell
The steps covered in part one and above are all well and good, but don’t you wish you could automate away a lot of that “point and click” stuff?
Sure no problem!
A Link To The Full Script
Whilst I’ll split out the build chunks of the PowerShell script required to complete each deployment step below, the full script can be found in my PowerShell Github Repository .
As mentioned, the script leverages NSX-T Data Center REST API (as detailed here ) calls to the NSX-T manager to create the required configuration.
To my knowledge and after extensive Googling, this is the first time such a script has been posted to the internet - certainly for the v3.2.0 NSX-T REST API.
Build Chunks
As I say, rather than “swallowing the elephant whole”, lets break the script down into more manageable chunks.
For brevity, I’ll cover PowerShell required to complete steps 3 to 12 of the deployment. OVA deployment automations already exist elsewhere so I will not cover them here.
PowerShell Variables
Lets create our PowerShell variables up front:
# =================================================================================================
# Update These:
$NSXUser = "admin" ## NSX-T Admin Username
$NSXPW = "Password123!Password123!" ## NSX-T Admin Password
$baseuri = "https://nsxt-site-b.lab" ## NSX-T Manager URL
$NSXTSite = "Site-B" ## NSX-T Site Name
# vCenter Connection # ============================
$vc = "vc-site-b.lab" ## vCenter Hostname
$VCSSOUser = "[email protected] " ## vCenter SSO Admin Username
$VCSSOPass = "Password123!" ## vCenter SSO Admin Password
$VCCluster = "SITE-B-CLUSTER" ## Cluster Name
$DVSwitch = "SITE-B-DSWITCH" ## Distributed Switch Name
$Datastore = "ESXi7-SITE-B-LOCAL" ## Datastore to deploy edge to
$MgmtDVPrtGrp = "Site-B-Management" ## Distributed Switch Port group for MGMT traffic
# Transport Zones # ===============================
$TZOvLySuffix = "Overlay-Transport-Zone" ## Overlay Transport Zone Name Suffix
$TZVlanSuffix = "VLAN-Transport-Zone" ## VLAN Transport Zone Name Suffix
# Host Uplink Profile # ===========================
$HUPSuffix = "Host-Uplink-Profile" ## Host Uplink Profile Name Suffix
$HUP1Name = "Uplink-1" ## Host Uplink 1 Name
$HUP2Name = "Uplink-2" ## Host Uplink 2 Name
$HUPTeaming = "FAILOVER_ORDER" ## Host Uplink Teaming Policy
$HTransVLAN = "21" ## Host Transport VLAN ID
# Edge Uplink Profile # ===========================
$EUPSuffix = "Edge-Uplink-Profile" ## Edge Uplink Profile Name Suffix
$EUP1Name = "Uplink-1" ## Edge Uplink 1 Name
$EUP2Name = "Uplink-2" ## Edge Uplink 2 Name
$EUPTeaming = "LOADBALANCE_SRCID" ## Edge Uplink Teaming Policy
$ETransVLAN = "21" ## Edge Transport VLAN ID
# TEP Pool # ======================================
$IPPSuffix = "TEP-Pool" ## TEP Pool Name Suffix
$IPPDescription = "Site-B TEP Pool" ## TEP Pool Description
$IPPStart = "192.168.21.2" ## TEP Pool Start IP
$IPPEnd = "192.168.21.254" ## TEP Pool End IP
$IPPCIDR = "192.168.21.0/24" ## TEP Pool CIDR
$IPPGW = "192.168.21.1" ## TEP Pool Gateway
# Transport Node Profile # ========================
$TNPSuffix = "Transport-Node-Profile" ## Transport Node Profile Name Suffix
# Edge VMs # ======================================
$EdgeNodes = @"
Edge,IP
esg-site-b,192.168.20.22
"@ | ConvertFrom-Csv ## List of Edge Nodes "Name","IP"
$EdgeCIDR = "24" ## Edge Management IP CIDR
$EdgeGWIP = "192.168.20.1" ## Edge Management IP Gateway
$EdgeDNSIP = "192.168.20.1" ## Edge DNS Server IP
$EdgeDNSSearch = "lab" ## Edge DNS Search List
$EdgeNTPIP = "192.168.20.1" ## Edge NTP Server List
$EdgeUplinks = "Site-B-Trunk" ## Distributed Switch Port group for Edge Uplinks
$EdgerootPW = $NSXPW ## Edge root User Password
$EdgeCLIPW = $NSXPW ## Edge CLI User Password
$EdgeCluSuffix = "Edge-Cluster" ## Edge Cluster Name Suffix
Handling API Response Exceptions
Lets create a PowerShell function so that we may correctly handle the API responses and exceptions returned from the NSX-T API:
# ==== HANDLE API RESPONSE EXCEPTIONS =============================================================
Function ResponseException {
#Get response from the exception
$response = $_ . exception . response
if ( $response ) {
Write-Host ""
Write-Host "Oops something went wrong, please check your API call" -ForegroundColor Red -BackgroundColor Black
Write-Host ""
$responseStream = $_ . exception . response . GetResponseStream ()
$reader = New-Object system.io.streamreader ( $responseStream )
$responseBody = $reader . readtoend ()
$Error String = "Exception occured calling invoke-restmethod. $( $response . StatusCode . value__ ) : $( $response . StatusDescription ) : Response Body: $( $responseBody ) "
Throw $Error String
Write-Host ""
}
else {
Throw $_
}
}
Accept Self-Signed Certificates and Handle Credentials
Let’s accept self-signed certificates:
# ==== ACCEPT CERTS + CREDENTIAL HANDLING =========================================================
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[ System.Net.ServicePointManager ]:: CertificatePolicy = New-Object TrustAllCertsPolicy
$pair = " $( $NSXUser ) : $( $NSXPW ) "
$bytes = [ System.Text.Encoding ]:: ASCII.GetBytes ( $pair )
$base64 = [ System.Convert ]:: ToBase64String ( $bytes )
$headers = @{
"Authorization" = "basic $base64 "
"Content-Type" = "application/json"
"Accept" = "application/json"
}
Create Transport Zones
This NSX-T API call will create our Overlay and VLAN Transport Zones:
# ==== CREATE TRANSPORT ZONES =====================================================================
$tzuri = " $baseuri /policy/api/v1/transport-zones/"
$body = @"
{
"display_name": " $( $NSXTSite ) - $( $TZOvLySuffix ) ",
"transport_type": "OVERLAY"
}
"@
Try {
$response = invoke-restmethod -uri $tzuri -headers $headers -method POST -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
$body = @"
{
"display_name": " $( $NSXTSite ) - $( $TZVlanSuffix ) ",
"transport_type": "VLAN"
}
"@
Try {
$response = invoke-restmethod -uri $tzuri -headers $headers -method POST -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Create Host Uplink Profile
This NSX-T API call will create our Host uplink profile:
# ==== CREATE HOST UPLINK PROFILE =================================================================
$hupuri = " $baseuri /policy/api/v1/infra/host-switch-profiles/ $NSXTSite - $HUPSuffix "
$body = @"
{
"display_name": " $( $NSXTSite ) - $( $HUPSuffix ) ",
"resource_type": "PolicyUplinkHostSwitchProfile",
"transport_vlan": $( $HTransVLAN ) ,
"teaming": {
"policy": " $( $HUPTeaming ) ",
"active_list": [
{
"uplink_name": "Uplink-1",
"uplink_type": "PNIC"
},
{
"uplink_name": "Uplink-2",
"uplink_type": "PNIC"
}
]
}
}
"@
Try {
$response = invoke-restmethod -uri $hupuri -headers $headers -method PATCH -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Create Edge Uplink Profile
This NSX-T API call will create our Edge uplink profile:
# ==== CREATE EDGE UPLINK PROFILE =================================================================
$eupuri = " $baseuri /policy/api/v1/infra/host-switch-profiles/ $NSXTSite - $EUPSuffix "
$body = @"
{
"display_name": " $( $NSXTSite ) - $( $EUPSuffix ) ",
"resource_type": "PolicyUplinkHostSwitchProfile",
"transport_vlan": $( $ETransVLAN ) ,
"teaming": {
"policy": " $( $EUPTeaming ) ",
"active_list": [
{
"uplink_name": "Uplink-1",
"uplink_type": "PNIC"
},
{
"uplink_name": "Uplink-2",
"uplink_type": "PNIC"
}
]
}
}
"@
Try {
$response = invoke-restmethod -uri $eupuri -headers $headers -method PATCH -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Create TEP Pool
This NSX-T API call will create our TEP IP pool and subnet:
# ==== CREATE TEP POOL =======================================================================================================================================
$ippooluri = " $baseuri /policy/api/v1/infra/ip-pools/ $NSXTSite - $IPPSuffix "
$body = @"
{
"display_name": " $( $NSXTSite ) - $( $IPPSuffix ) "
}
"@
Try {
$response = invoke-restmethod -uri $ippooluri -headers $headers -method PATCH -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
# ==== CREATE TEP POOL SUBNET ================================================================================================================================
$ippoolsubneturi = " $baseuri /policy/api/v1/infra/ip-pools/ $NSXTSite - $IPPSuffix /ip-subnets/Subnet-1"
$body = @"
{
"resource_type": "IpAddressPoolStaticSubnet",
"allocation_ranges": [
{
"start": " $IPPStart ",
"end": " $IPPEnd "
}
],
"cidr": " $IPPCIDR ",
"gateway_ip": " $IPPGW "
}
"@
Try {
$response = invoke-restmethod -uri $ippoolsubneturi -headers $headers -method PATCH -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Attach vCenter
This NSX-T API call will attach our vCenter as a Compute Manager in NSX-T:
# ==== ADD vCENTER ================================================================================
Try {
$response = invoke-restmethod -uri "https:// $vc " -Method Get | Out-Null
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
$EndPoint = [ System.Net.Webrequest ]:: Create ( "https:// $vc " )
$cert = $EndPoint . ServicePoint . Certificate
$BYTES = $cert . Export ([ Security.Cryptography.X509Certificates.X509ContentType ]:: Cert )
Set-content -value $BYTES -encoding byte -path $ ENV : TMP \cert-temp
$VCThumbprint = (( Get-FileHash -Path $ ENV : TMP \cert-temp -Algorithm SHA256 ) . Hash ) -replace '(..(?!$))' , '$1:'
$VCHost = " $( $EndPoint . Host ) "
$addcompmgruri = " $baseuri /api/v1/fabric/compute-managers"
$body = @"
{
"server": " $( $VCHost ) ",
"origin_type": "vCenter",
"display_name": " $( $VCHost . ToUpper () ) ",
"credential" : {
"credential_type" : "UsernamePasswordLoginCredential",
"username": " $( $VCSSOUser ) ",
"password": " $( $VCSSOPass ) ",
"thumbprint": " $( $VCThumbprint ) "
}
}
"@
Try {
$response = invoke-restmethod -uri $addcompmgruri -headers $headers -method POST -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Create Transport Node Profile
This NSX-T API call will create our Transport node profile:
# ==== CREATE TRANSPORT NODE PROFILE ==============================================================
# Get DVS ID
$vctr = Connect-VIServer $vc -User " $VCSSOUser " -Password $VCSSOPass #-WarningAction SilentlyContinue
$vds = ( Get-VDSwitch -Name " $DVSwitch " -Server " $vc " ) . ExtensionData
$vdsuuid = $vds . Uuid
Disconnect-VIServer $vc -Confirm : $false
# Get transport zone IDs
$uri = " $baseuri /policy/api/v1/transport-zones"
Try {
$response = invoke-restmethod -uri $uri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
foreach ( $zone in $ ( $response . results )) {
if ( $zone . display_name -eq " $( $NSXTSite ) - $( $TZOvLySuffix ) " ) { $ovlytzid = $zone . id }
if ( $zone . display_name -eq " $( $NSXTSite ) - $( $TZVlanSuffix ) " ) { $vlantzid = $zone . id }
}
# Create Profile
$tnpuri = " $baseuri /policy/api/v1/infra/host-transport-node-profiles/ $NSXTSite - $TNPSuffix "
$body = @"
{
"host_switch_spec": {
"host_switches": [
{
"host_switch_name": "nsxDefaultHostSwitch",
"host_switch_id": " $( $vdsuuid ) ",
"host_switch_type": "VDS",
"host_switch_mode": "STANDARD",
"host_switch_profile_ids": [
{
"key": "UplinkHostSwitchProfile",
"value": "/infra/host-switch-profiles/ $( $NSXTSite ) - $( $HUPSuffix ) "
}
],
"uplinks": [
{
"vds_uplink_name": "Uplink 1",
"uplink_name": "Uplink-1"
},
{
"vds_uplink_name": "Uplink 2",
"uplink_name": "Uplink-2"
}
],
"is_migrate_pnics": false,
"ip_assignment_spec": {
"ip_pool_id": "/infra/ip-pools/ $( $NSXTSite ) - $( $IPPSuffix ) ",
"resource_type": "StaticIpPoolSpec"
},
"cpu_config": [],
"transport_zone_endpoints": [
{
"transport_zone_id": "/infra/sites/default/enforcement-points/default/transport-zones/ $ovlytzid "
},
{
"transport_zone_id": "/infra/sites/default/enforcement-points/default/transport-zones/ $vlantzid "
}
],
"not_ready": false
}
],
"resource_type": "StandardHostSwitchSpec"
},
"ignore_overridden_hosts": false,
"resource_type": "PolicyHostTransportNodeProfile",
"display_name": " $( $NSXTSite ) - $( $TNPSuffix ) "
}
"@
Try {
$response = invoke-restmethod -uri $tnpuri -headers $headers -method PUT -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Prepare Cluster
This NSX-T API call will apply our transport node profile to our compute cluster:
# ==== PREPARE CLUSTER ============================================================================
# Get Compute Cluster ID
$uri = " $baseuri /api/v1/fabric/compute-collections"
Try {
$response = invoke-restmethod -uri $uri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
foreach ( $collection in $ ( $response . results )) {
if ( $collection . display_name -eq " $VCCluster " ) { $collectid = $collection . external_id }
}
# Prepare Cluster
$prepuri = " $baseuri /policy/api/v1/infra/sites/default/enforcement-points/default/transport-node-collections/TNC"
$body = @"
{
"resource_type": "HostTransportNodeCollection",
"compute_collection_id": " $collectid ",
"transport_node_profile_id": "/infra/host-transport-node-profiles/ $( $NSXTSite ) - $( $TNPSuffix ) "
}
"@
Try {
$response = invoke-restmethod -uri $prepuri -headers $headers -method PUT -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Sleep 300 # Wait 5 mins for Cluster Preparation
Check Host TEP Connectivity
Lets log on to our host and confirm it can ping the TEP VLAN gateway:
Yep, looks good.
Create Trunk VLAN Segment
This NSX-T API call will create our Trunk VLAN segment:
# ==== CREATE TRUNK VLAN SEGMENT ==================================================================
$seguri = " $baseuri /policy/api/v1/infra/segments/ $NSXTSite -Trunk"
$body = @"
{
"display_name": " $NSXTSite -Trunk",
"vlan_ids": [
"0-4094"
],
"transport_zone_path": "/infra/sites/default/enforcement-points/default/transport-zones/ $vlantzid "
}
"@
Try {
$response = invoke-restmethod -uri $seguri -headers $headers -method PUT -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Create Edge Node(s)
This NSX-T API call will create our Edge node:
# ==== CREATE EDGE NODES ==========================================================================
# Get Edge Uplink Profile ID
$eupuri = " $baseuri /policy/api/v1/infra/host-switch-profiles/ $NSXTSite - $EUPSuffix "
Try {
$response = invoke-restmethod -uri $eupuri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
$eupid = $response . unique_id
# Get IP Pool ID
$ippooluri = " $baseuri /policy/api/v1/infra/ip-pools/ $NSXTSite - $IPPSuffix "
Try {
$response = invoke-restmethod -uri $ippooluri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
$ippid = $response . unique_id
# Get Overlay Transport Zone IDs
$tzuri = " $baseuri /policy/api/v1/transport-zones/"
Try {
$response = invoke-restmethod -uri $tzuri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
foreach ( $zone in $ ( $response . results )) {
if ( $zone . display_name -eq " $( $NSXTSite ) - $( $TZOvLySuffix ) " ) { $ovlytzid = $zone . id }
if ( $zone . display_name -eq " $( $NSXTSite ) - $( $TZVlanSuffix ) " ) { $vlantzid = $zone . id }
}
# Get IDs from vCenter
$vctr = Connect-VIServer $vc -User " $VCSSOUser " -Password $VCSSOPass #-WarningAction SilentlyContinue
$vds = ( Get-VDSwitch -Name " $DVSwitch " -Server " $vc " ) . ExtensionData
$vdsuuid = $vds . Uuid
$storid = ( Get-Datastore -Name " $Datastore " -Server " $vc " ) . ExtensionData . MoRef . Value
$mgtprtgrp = ( Get-VirtualPortgroup -Name " $MgmtDVPrtGrp " ) . key
$computeid = ( Get-Cluster -Name $VCCluster ) . ExtensionData . moref . value
Disconnect-VIServer $vc -Confirm : $false
# Create Edges
$edgeuri = " $baseuri /api/v1/transport-nodes"
ForEach ( $Node in $EdgeNodes ){
$body = @"
{
"display_name": " $( ( $Node . Edge ) .ToUpper())",
"host_switch_spec": {
"host_switches": [
{
"host_switch_name": "N-DVS-01",
"host_switch_type": "NVDS",
"host_switch_mode": "STANDARD",
"host_switch_profile_ids": [
{
"key": "UplinkHostSwitchProfile",
"value": " $eupid "
}
],
"pnics": [
{
"device_name": "fp-eth0",
"uplink_name": "Uplink-1"
},
{
"device_name": "fp-eth1",
"uplink_name": "Uplink-2"
}
],
"is_migrate_pnics": false,
"ip_assignment_spec": {
"ip_pool_id": " $ippid ",
"resource_type": "StaticIpPoolSpec"
},
"cpu_config": [],
"transport_zone_endpoints": [
{
"transport_zone_id": " $ovlytzid ",
"transport_zone_profile_ids": [
{
"resource_type": "BfdHealthMonitoringProfile",
"profile_id": "52035bb3-ab02-4a08-9884-18631312e50a"
}
]
},
{
"transport_zone_id": " $vlantzid ",
"transport_zone_profile_ids": [
{
"resource_type": "BfdHealthMonitoringProfile",
"profile_id": "52035bb3-ab02-4a08-9884-18631312e50a"
}
]
}
],
"not_ready": false
}
],
"resource_type": "StandardHostSwitchSpec"
},
"maintenance_mode": "DISABLED",
"node_deployment_info": {
"deployment_type": "VIRTUAL_MACHINE",
"deployment_config": {
"vm_deployment_config": {
"vc_id": " $vcid ",
"compute_id": " $computeid ",
"storage_id": " $storid ",
"management_network_id": " $mgtprtgrp ",
"management_port_subnets": [
{
"ip_addresses": [
" $( $Node . IP ) "
],
"prefix_length": " $EdgeCIDR "
}
],
"default_gateway_addresses": [
" $EdgeGWIP "
],
"data_network_ids": [
"/infra/segments/ $EdgeUplinks ",
"/infra/segments/ $EdgeUplinks "
],
"reservation_info": {
"memory_reservation": {
"reservation_percentage": 0
},
"cpu_reservation": {
"reservation_in_shares": "NORMAL_PRIORITY",
"reservation_in_mhz": 0
}
},
"placement_type": "VsphereDeploymentConfig"
},
"form_factor": "SMALL",
"node_user_settings": {
"cli_username": "admin",
"root_password":" $EdgerootPW ",
"cli_password":" $EdgeCLIPW "
}
},
"node_settings": {
"hostname": "esg-site-b.lab",
"search_domains": [
" $EdgeDNSSearch "
],
"ntp_servers": [
" $EdgeNTPIP "
],
"dns_servers": [
" $EdgeDNSIP "
],
"enable_ssh": true,
"allow_ssh_root_login": true
},
"resource_type": "EdgeNode",
"ip_addresses": [
" $( $Node . IP ) "
]
}
}
"@
Try {
$response = invoke-restmethod -uri $edgeuri -headers $headers -method POST -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Sleep 300 # Wait 5 mins for Edge Deployment(s)
}
Check Edge TEP Connectivity
Lets log on to our edge and confirm it can ping the TEP VLAN gateway:
Looks good.
Create Edge Cluster
This NSX-T API call will create our Edge node cluster:
# ==== CREATE EDGE CLUSTER ========================================================================
# Get Edge Nodes
$edgeuri = " $baseuri /api/v1/transport-nodes"
Try {
$response = invoke-restmethod -uri $edgeuri -headers $headers -method GET
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
$Edgenodes = $response . results . Where { $_ . node_deployment_info . deployment_type -eq "VIRTUAL_MACHINE" }
$memberlist = @()
ForEach ( $Edgenode in $Edgenodes ){
$out = new-object psobject
$out | Add-Member noteproperty "transport_node_id" " $( $edgenode . id ) "
$out | Add-Member noteproperty "display_name" " $( $edgenode . display_name ) "
$memberlist += $out
}
$memberlistjson = $memberlist | ConvertTo-Json
# Create Edge Cluster
$edcluuri = " $baseuri /api/v1/edge-clusters"
$body = @"
{
"member_node_type": "EDGE_NODE",
"resource_type": "EdgeCluster",
"display_name": " $( $NSXTSite ) - $( $EdgeCluSuffix ) ",
"deployment_type": "VIRTUAL_MACHINE",
"members": $( $memberlistjson ) ,
"cluster_profile_bindings": [
{
"resource_type": "EdgeHighAvailabilityProfile",
"profile_id": "91bcaa06-47a1-11e4-8316-17ffc770799b"
}
]
}
"@
Try {
$response = invoke-restmethod -uri $edcluuri -headers $headers -method POST -body $body
$response
Write-Host "" }
Catch { ResponseException # Call Function ResponseException to get error response from the exception
}
Conclusion and Wrap Up
We made it!
In this post we deployed NSX-T into and configured our second site (the imaginatively named) Site B ready to receive NSX-T federation, in double quick time.
Again the full script used above can be found in my PowerShell Github Repository .
Whilst we don’t yet have all the configuration in place in Site B to produce a half a working cross site NSX-T federated setup, we are well on the way.
We still have to create our Global Tier 0 and Tier 1 Logical routers before we can hook any VMs into our NSX-T build. We will look at that in the next part of this series.
This was part 3 of a multipart series. Find the other parts here:
Look out for future parts coming soon!
-Chris