Deploy VMware Cloud on AWS Route Based VPN with API

Gilles Chekroun
Lead VMware Cloud on AWS Specialist
---
Following my articles on AWS Transit Gateway here and here, I found it quite complex to setup the VPN connection and the 2 tunnels from TGW VPN attachment to VMC route based VPN using the GUI.

AWS VPN Naming and VMC VPN relationship

When creating the AWS TGW VPN attachment, AWS gives the possibility to "download configuration file"

AWS - VMC relationship:

Once this is clear, it's time to map these parameters to our API Calls.

Five API calls 

For properly setting a Route Based VPN to AWS TGW we need 5 API calls:
  • Get the NSX-T Proxy URL
  • Get the SDDC Public IP
  • Set Local AS Number
  • Set BGP Neighbour ID
  • Set VPN Tunnels
Before we can do any API calls into VMC we need a few parameter like "Refresh-Token", "Org-ID", "SDDC-ID". Refer to my earlier post here on how to get them.

Get NSX-T Proxy URL

This API call will get "Org-ID, SDDC-ID and Session-Token" and will return the NSX-T Proxy URL you need in the subsequent calls

def getNSXTproxy(org_id, sddc_id, sessiontoken):
    myHeader = {'csp-auth-token': sessiontoken}
    myURL = "{}/vmc/api/orgs/{}/sddcs/{}".format(strProdURL, org_id, sddc_id)
    response = requests.get(myURL, headers=myHeader)
    json_response = response.json()
    proxy_url = json_response['resource_config']['nsx_api_public_endpoint_url']
    overview_url = (proxy_url + "/cloud-service/api/v1/infra/sddc-user-config")
    return overview_url

Get SDDC Public IP

This API Call will retrieve the SDDC Public IP
def getSDDCpublicIP(proxy_url, sessiontoken):
    myHeader = {'csp-auth-token': sessiontoken}
    myURL = proxy_url
    response = requests.get(myURL, headers=myHeader)
    json_response = response.json()
    pub_IP = json_response['vpn_internet_ips'][0]
    return pub_IP

Set Local AS Number

The default Local ASN is 64512 - you can set ASN between 64512 and 65534
This API call will get "Org-ID, SDDC-ID, Session-Token and ASN Number" and will set it.
def set_bgp_asn(proxy_url, org_id, sddc_id, sessiontoken, vmc_asn):
    myHeader = {
        'csp-auth-token': sessiontoken,        'content-type': 'application/json'    }
    myURL = "{}/api/orgs/{}/sddcs/{}/sks-nsxt-manager/policy/api/v1/infra/tier-0s/
vmc/locale-services/default/bgp".format(proxy_url, org_id, sddc_id)
    payload = {
        "local_as_num": vmc_asn
        }
    response = requests.patch(myURL, json=payload, headers=myHeader)
    json_response = response.json()
    print(json_response)
    return

Set BGP Neighbour ID

This API call will set the proper BGP neighbour ID to use on the next call
def setBGPnb(proxy_url, org_id, sddc_id, sessiontoken,neighbor_id, remote_asn, remote_ip):
    myHeader = {'csp-auth-token': sessiontoken}
    myURL = "{}/api/orgs/{}/sddcs/{}/sks-nsxt-manager/policy/api/v1/infra/tier-0s/
vmc/locale-services/default/bgp/neighbors/{}".format(proxy_url, org_id, 
sddc_id, neighbor_id)
    strRequest = {
        "resource_type": "BgpNeighborConfig",
        "id": neighbor_id,
        "remote_as_num": remote_asn,
        "neighbor_address": remote_ip
    }
    response = requests.put(myURL, json=strRequest, headers=myHeader)
    json_response = response.json()
    if str(response.status_code) != "200":
        print(json_response)
    return

Set VPN Tunnels

This API call will create one VPN Tunnel using the parameters from the AWS side configuration file.
def setVPN(proxy_url, org_id, sddc_id, sessiontoken, name, public_ip, remote_ip, local_ip, 
passw, neighbor_id):
    myHeader = {'csp-auth-token': sessiontoken}
    myURL = "{}/api/orgs/{}/sddcs/{}/sks-nsxt-manager/policy/api/v1/infra/tier-0s/
vmc/locale-services/default/l3vpns/{}".format(proxy_url, org_id, sddc_id, name)
    strRequest = {
        "display_name": name,
        "enabled": "true",
        "local_address": public_ip,
        "remote_private_address": remote_ip,
        "remote_public_address": remote_ip,
        "passphrases": [passw],
        "tunnel_digest_algorithms": ["SHA2_256"],
        "ike_digest_algorithms": ["SHA2_256"],
        "ike_encryption_algorithms": ["AES_256"],
        "enable_perfect_forward_secrecy": "true",
        "dh_groups": ["GROUP14"],
        "ike_version": "IKE_V1",
        "l3vpn_session": {
            "resource_type": "RouteBasedL3VpnSession",
            "tunnel_subnets": [
                {
                    "ip_addresses": [
                        local_ip
                    ],
                    "prefix_length": 30
                }
            ],
            "default_rule_logging": "false",
            "force_whitelisting": "false",
            "routing_config_path": "/infra/tier-0s/vmc/locale-services/default/bgp/neighbors/{}"
.format(neighbor_id)
        },
        "tunnel_encryption_algorithms": ["AES_256"]
    }
    response = requests.put(myURL, json=strRequest, headers=myHeader)
    json_response = response.json()
    if str(response.status_code) != "200":
        print(json_response)
    return

Main procedure for setting up the VPN Tunnels


# --------------------------------------------
# ---------------- Main ----------------------
# --------------------------------------------
session_token = getAccessToken(Refresh_Token)
sddcID = getSDDC_ID(ORG_ID, session_token)
proxy = getNSXTproxy(ORG_ID, sddcID, session_token)
set_bgp_asn(proxy, ORG_ID, sddcID, session_token, VMC_ASN)
Public_IP = getSDDCpublicIP(proxy,session_token)
neighbor_1 = "IPSEC_T1"
neighbor_2 = "IPSEC_T2"
setBGPnb(proxy,ORG_ID, sddcID,session_token, neighbor_1, T1_BGP_remote_ASN, T1_BGP_remote_ip)
print("Tunnel 1 IPsec OK")
setVPN(proxy, ORG_ID, sddcID, session_token, "Tunnel-1", Public_IP, T1_remote_public_ip, T1_BGP_local_ip, T1_pass, neighbor_1)
print("Tunnel 1 route based VPN OK")
setBGPnb(proxy,ORG_ID, sddcID,session_token, neighbor_2, T2_BGP_remote_ASN, T2_BGP_remote_ip)
print("Tunnel 2 IPsec OK")
setVPN(proxy, ORG_ID, sddcID, session_token, "Tunnel-2", Public_IP, T2_remote_public_ip, T2_BGP_local_ip, T2_pass, neighbor_2)
print("Tunnel 2 route based VPN OK")




Results on the VMware Cloud on AWS SDDC GUI


THANK YOU !!

Comments

Populars

Understanding VMware Cloud on AWS Account Structure and Data Charges

Create a vCenter Content Library using AWS S3 - Part 2

Build a VMware Cloud on AWS Content Library using AWS S3