Automating VCF 4.0 Edge Cluster Creation

Today, VMware Cloud Foundation (VCF) 4.0 was released. One of the new features mentioned in the release notes is how the SDDC Manager now can automate the deployment of NSX Edge Clusters. Today, I’m going to show you how to automate that automation.

I tend to deploy VMware Cloud Foundation a lot. The web-based interface is pretty easy to use. However, there is a lot of information that is required in order to perform certain tasks. I have often mis-typed some value or name, which results in some interesting issues to troubleshoot. This gets worse the more times I have to perform the task. To avoid any human errors, I try to automate the bigger tasks using the API. One such task is the creation of the Edge Clusters.

We could just make an API call and specify all the values we need. However, I prefer to use a JSON formatted file to define the payload. This allows me to easily modify the file and simply reference the file on my command line.

The API spec for creating a edge cluster would look similar to this:                  

{
        "edgeClusterName": "wld1-edge-cluster",
        "edgeClusterType": "NSX-T",
        "edgeRootPassword": "VMware123!VMware123!",
        "edgeAdminPassword": "VMware123!VMware123!",
        "edgeAuditPassword": "VMware123!VMware123!",
        "edgeFormFactor": "LARGE",
        "tier0ServicesHighAvailability": "ACTIVE_ACTIVE",
        "mtu": 8940,
        "asn": 65004,
        "tier0RoutingType": "EBGP",
        "tier0Name": "wld1-T0",
        "tier1Name": "wld1-T1",
        "edgeClusterProfileType": "DEFAULT",
        "edgeNodeSpecs": [{
                        "edgeNodeName": "esg-3.vcf.sddc.local",
                        "managementIP": "10.0.0.49/24",
                        "managementGateway": "10.0.0.1",
                        "edgeTepGateway": "172.27.16.1",
                        "edgeTep1IP": "172.27.16.2/24",
                        "edgeTep2IP": "172.27.16.3/24",
                        "edgeTepVlan": 16,
                        "clusterId": "CLUSTERID",
                        "interRackCluster": "false",
                        "uplinkNetwork": [{
                                        "uplinkVlan": 14,
                                        "uplinkInterfaceIP": "172.27.14.2/24",
                                        "peerIP": "172.27.14.1/24",
                                        "asnPeer": 65001,
                                        "bgpPeerPassword": "VMware123!"
                                },
                                {
                                        "uplinkVlan": 15,
                                        "uplinkInterfaceIP": "172.27.15.2/24",
                                        "peerIP": "172.27.15.1/24",
                                        "asnPeer": 65001,
                                        "bgpPeerPassword": "VMware123!"
                                }
                        ]
                },
                {
                        "edgeNodeName": "esg-4.vcf.sddc.local",
                        "managementIP": "10.0.0.50/24",
                        "managementGateway": "10.0.0.1",
                        "edgeTepGateway": "172.27.16.1",
                        "edgeTep1IP": "172.27.16.4/24",
                        "edgeTep2IP": "172.27.16.5/24",
                        "edgeTepVlan": 16,
                        "clusterId": "CLUSTERID",
                        "interRackCluster": "false",
                        "uplinkNetwork": [{
                                        "uplinkVlan": 14,
                                        "uplinkInterfaceIP": "172.27.14.3/24",
                                        "peerIP": "172.27.14.1/24",
                                        "asnPeer": 65001,
                                        "bgpPeerPassword": "VMware123!"
                                },
                                {
                                        "uplinkVlan": 15,
                                        "uplinkInterfaceIP": "172.27.15.3/24",
                                        "peerIP": "172.27.15.1/24",
                                        "asnPeer": 65001,
                                        "bgpPeerPassword": "VMware123!"
                                }
                        ]
                }
        ]
}
 

Most of values should be self-explainable. There is one that deserves some explanation. That would be the value for the clusterId attribute. This attribute has CLUSTERID as its value, which isn’t really a valid cluster ID.

The reason for this is because I’m lazy.

In order to do this manually, I would first have to use the API to get the AUTH token (so I could run more API commands), then get the list of clusters and the corresponding cluster ID. I’d then have to edit the JSON file, add the cluster ID in, validate it, and then actually trigger it. Sounds like a perfect time for a quick bash script. Which is what I did…

The following script is a really basic script I called ‘do_magic.sh’. There is very little error handling in it, so beware.  The idea is that you can copy this script to the SDDC Manager. You also need to save the JSON spec listed above to a file called ‘edge_cluster.json’ and place it in the same directory on the SDDC Manager where you placed the script.

#!/bin/bash

echo "Starting magic..."
token=`curl -X POST -H "Content-Type: application/json" -d '{"username": "administrator@vsphere.local","password": "VMware123!"}' --insecure https://10.0.0.4/v1/tokens | awk -F "\"" '{ print $4}'`

clus_id=`curl -X GET --insecure -H 'Content-Type: application/json' -H "Authorization: Bearer $token" 'https://localhost/v1/clusters' -k | jq '.elements | .[1].id'|tr -d '"'`

sed "s/CLUSTERID/$clus_id/g" edge_cluster.json > modified_edge_cluster.json

echo "Doing Validation..."
validate_id=`curl --insecure -H 'Content-Type: application/json' -H "Authorization: Bearer $token" 'https://localhost/v1/edge-clusters/validations' -d @modified_edge_cluster.json -k | jq '.id'|tr -d '"'`

echo -e "\n\nPlease wait. Validation takes a minute.\n"
sleep 60
status=`curl -X GET --insecure -H 'Content-Type: application/json' -H "Authorization: Bearer $token" "https://localhost/v1/edge-clusters/validations/$validate_id" -k | jq '.resultStatus'|tr -d '"'`
if [ $status == 'SUCCEEDED' ]
then
  echo "Shake 'n bake!"
curl -X POST --insecure -H 'Content-Type: application/json' -H "Authorization: Bearer $token" 'https://localhost/v1/edge-clusters' -d @modified_edge_cluster.json -k | json_pp
else
  echo "Failure detected. Go check things and try again."
fi
 
echo -e "All done.\n"

When you execute the script, it will use curl to get the AUTH token needed. It stores this token and then uses it for the remaining API commands.

Next, it will get the cluster ID. This script expects that there is a management domain and one VI workload domain already created. If this is not the case in your environment, you will need to modify the script.

After this, it looks for that edge_cluster.json file in the same directory. It uses this file as a template to make a copy of the file and replace the CLUSTERID keyword with the actual cluster ID. It saves this as a new file called ‘modified_edge_cluster.json’. This file is what is then used as the actual payload for the edge cluster creation API call. There’s no cleanup of that file, as it’s easier to troubleshoot.

After this, it does a validation and makes sure that completes successfully. If so, it goes ahead and kicks off the edge cluster creation. From here, you can use the SDDC Manager UI and monitor the tasks.

Again, this is very basic, so use at your own risk. Here’s what it looks like when you run the script. Have fun!