VCF - Automate VMware Cloud Foundation - Service Provider - bringup process using PowerShell
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