6 minute read

VMware Cloud Foundation (VCF) is an integrated software stack that uses SDDC Manager as a tool to automate the deployment and lifecycle management.

One of the main diferences in the VCF SP version is the lack of web interface to initiate the bringup process, everything in VCF SP version is done through the API.

The post will be a quick runthrough the automation of the bringup process using Powershell.

All the code snippets have the objective to help creating your own bringup automation script, even being a working piece of code if copy&pasted there are parts where more code is needed, as an example, there is no code or reference in how to generate the JSON payload (possible a future post) so you will need to fill the gap between having the info and getting it to a VCF SP valid JSON payload.

Initial Challenge

When planning the process there is a first challenge that we need to address will be how to to reach the API, since the API service is only listening in the 127.0.0.1 (localhost) port 9080.

After some research found a nice Powershell module that would help with SSH connectivity - Posh-SSH

There were 2 options how to address SSH connectivity:

  • SSH into the bringup box and then run the commands through the shell
  • Initiate a SSH session and then use it as a tunnel to forward the traffic via a port forward

We will be using the second approach since the initial idea was to use Powershell.

Step 1 - Establishing SSH tunnel and setup portforward

Initiating SSH conection

# Variables
$deployVMIP       = "192.168.0.30" # FQDN/IP
$deployVMUsername = "root"         # SSH username
$deployVMPassword = "password"     # SSH password

# Setting up tunnel
$sshConnection = New-SSHConnection -destination $deployVMIP `
    -username $deployVMUsername -password $deployVMPassword

Setting up the portforward

# Variables
$localPort       = 9000 # Local port to use
$deployVMTCPPort = 9080 # Remote port
$sshConnection          # SSH connection established

# Setup Portforward
New-SSHLocalPortForward -BoundHost "127.0.0.1" -BoundPort $localPort `
    -RemoteAddress "127.0.0.1" -RemotePort $deployVMTCPPort `
    -SSHSession $sshConnection

Step 2 - Checkup if bingup service is up and running

From now on, since we have a SSH connection and a local portforward, we will use the localhost and localPort in the URLs for the API calls instead of deploy VM address.

# Variables
$url = "http://localhost:$localPort/bringup-app/bringup/about"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type" , "application/json")

# GET Rest API Call to check if bringup service is up
if (($request = Get-RestAPICall -url $url -headers $headers).name -notmatch "BRINGUP") {
    Write-Host "--> bringup - Bringup service is not UP <--" -ForegroundColor Red
    Exit
} else {
    Write-Host "--> bringup - Bringup service is UP and running <--" `
        -ForegroundColor Green
    Write-Host "--> bringup - $($request.name) - $($request.serviceId) - $($request.version) <--" `
        -ForegroundColor Green
}

Get-RestAPICall is one of the wrapping functions already exemplified in an earlier post Powershell - Wrapping GET and POST Rest API calls

Step 3 - Start bringup process

Now that we checked if the bringup service is running and our ssh tunnel/portforwarding is good, we can start the bringup process by using a POST request.

# Variables
$vcfJSON = <JSON payload> # More info in the note below

$url = "http://localhost:$localPort/bringup-app/bringup/sddcs"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type" , "application/json")
$headers.Add("Content-Accept" , "application/json")

$request = Post-RestAPICall -url $url -headers $headers -payload $vcfJSON

# Store the bringup_ID process to be used later to check the progress
$bringupId = $request.id

$vcfJSON - will have the JSON payload that we will send in the POST command to the API, there will be multiple ways of creating this payload either by using a template and replace the fields with string replacemente or even building the full JSON payload from scratch using Powershell, didn’t detail any of the options, since it would be a familiar process to someone working with VCF SP

Post-RestAPICall is one of the wrapping functions already exemplified in an earlier post Powershell - Wrapping GET and POST Rest API calls

Step 4 - Waiting till VCF finishes the deployment

The VCF deployment process can take some time to finish, since it will perform multiple validations and some of the installations processes will take its time.

In our particular case, being this our Nested Lab Environemnt, it tipically take 2h30/3h30 to deploy, depending on the current physical cluster utilization:

  • 4 Nested ESXi
  • 1 Platform Service Constroller (PSC)
  • 1 vCenter (VCSA)
  • 1 NSX Manager
  • 1 NSX Controller cluster (3x NSX Controllers)

Setting up a simple waiting cycle to wait for the bringup process to finish, instead of chasing the progress from time to time.

# Variables
$counter = 0               # Counter to keep track of elapsed time (no guaranteed accuracy)
$BRINGUP_WAIT_TIMEOUT = 60 # Timer in seconds between checks

do {
    Start-Sleep -Seconds $BRINGUP_WAIT_TIMEOUT
    $counter++
    if ((($counter * $BRINGUP_WAIT_TIMEOUT) % 600) -eq 0) {
        $ts = [timespan]::fromseconds( $counter * $BRINGUP_WAIT_TIMEOUT )
        Write-Host "($($ts.Hours.ToString("00"))h$($ts.Minutes.ToString("00"))m)" -ForegroundColor Yellow
    } else {
        Write-Host -NoNewline "#" -ForegroundColor Yellow
    }

    # Check if SSH tunnel is UP and Portforward is setup, since we will need it to keep checking
    if ( !($sshTunnelSession.Connected) ) {
        # tunnel down lets reconnect and recreate the port forward
        Write-Host "--> bringup - Tunnel Down - Reconnect <--" -ForegroundColor Red
        $sshTunnelSession = New-SSHConnection -destination $deployVMIP `
            -username $deployVMUsername -password $deployVMPassword
    } else {
        # Check portforward
        if (!(Get-SSHPortForward -SSHSession $sshTunnelSession | `
            Where-Object { ($_.BoundPort -match $localPort) -and ($_.IsStarted) } )) {
                # Setup Portforward
                New-SSHLocalPortForward -BoundHost "127.0.0.1" -BoundPort $localPort `
                    -RemoteAddress "127.0.0.1" -RemotePort $deployVMTCPPort `
                    -SSHSession $sshTunnelSession
        }
    }

    $request = Get-RestAPICall -headers $headers -url $url
} while($request -match "IN_PROGRESS")

switch ($request){
    "COMPLETED_WITH_FAILURE" {
        Write-Host "`n-> VCF Bringup COMPLETED WITH FAILURE - $request <-" `
            -ForegroundColor Red
    }
    "COMPLETED_WITH_SUCCESS" {
        Write-Host "`n-> VCF Bringup FINISHED OK - $request <-" `
            -ForegroundColor Green
    }
    default {
        Write-Host "`n-> VCF Bringup FINISHED - Unexpected State - $request <-" `
            -ForegroundColor Blue
    }
}

Step 5 - Kill the SSH tunnel/porforward

Once we finished the bringup, we can shut the SSH tunnel

# Kill SSH Tunnel
$null = Remove-SSHSession $sshTunnelSession