Using API Tokens for VCD 10.3.1 from PowerCLI and Terraform

I had some queries on my previous blog post on using the new API Tokens in VMware Cloud Director (VCD) 10.3.1 about whether these can be used in PowerCLI scripts from PowerShell or Terraform scripts which use the VMware Terraform Provider against Cloud Director. Fortunately the answer to both questions is 'Yes' and I've created a small github repository with examples of how these can be done.

For both scripts the variables need to be set to something appropriate:

org should be set to the 'short' organization code for VCD (the same name as you'd use after 'tenant' when accessing the VCD UI)
vcdhost should be set to the FQDN of the VCD environment you are using (e.g. cloud.my.service.provider.net)
token should be set to the API Token value created in VCD

For PowerCLI we can use the SessionId returned from first refreshing the API token and then accessing the /api/session path to login with Connect-CIServer which provides full access to all PowerCLI cmdlets, the script to do this is included below and in the Github repository as vcd-token.ps1.

 1$org = "<VCD Organization Code>"
 2$vcdhost = "<VCD Hostname>"
 3$token = "<VCD API Token String>"
 4
 5# Use the token to generate an access-token
 6try {
 7  $uri = "https://$($vcdhost)/oauth/tenant/$($org)/token?grant_type=refresh_token&refresh_token=$($token)"
 8  $access_token = (Invoke-RestMethod -Method Post -Uri $uri -Headers @{'Accept' = 'application/json'}).access_token
 9  Write-Host -ForegroundColor Green ("Created access_token from token successfully")
10} catch {
11  Write-Host -ForegroundColor Red ("Could not create access_token from token, response code: $($_.Exception.Response.StatusCode.value__)")
12  Write-Host -ForegroundColor Red ("Status Description: $($_.Exception.Response.ReasonPhrase).")
13}
14
15# Use the access-token to get a SessionId from the x-vcloud-authorization header response:
16$headers = @{"Accept" = "application/*+xml;version=36.1"; "Authorization" = "Bearer $($access_token)"}
17try {
18  $SessionId = [string](Invoke-WebRequest -Method Get -Uri "https://$($vcdhost)/api/session" -Headers $headers).headers.'x-vcloud-authorization'
19  Write-Host -ForegroundColor Green ("Got SessionId from access_token successfully")
20} catch {
21  Write-Host -ForegroundColor Red ("Could not create SessionId from access_token, response code: $($_.Exception.Response.StatusCode.value__)")
22  Write-Host -ForegroundColor Red ("Status Description: $($_.Exception.Response.ReasonPhrase).")
23}
24
25# Create a new PowerCLI connection using the returned SessionId:
26Connect-CIServer -Server $vcdhost -SessionId $SessionId
27
28# Example PowerCLI to return all VMs in Org:
29Get-CIVM | Format-Table
30
31# (Optional) Disconnect the CIServer session:
32Disconnect-CIServer -Server $vcdhost -Confirm:$false

Usage should be pretty straightforward - just change the variables at the top of the file for the VCD Organization code, VCD API hostname and the Token generated in the VCD UI and the commands at the bottom of the file as appropriate.

For Terraform, we can use a small Bash script in a similar way to set a VCD_TOKEN environment variable which can then be consumed by the VCD Terraform Provider to authenticate when applying Terraform plans. This script is in the Github repository as vcd-token.sh.

 1#!/bin/bash
 2
 3org="<VCD Organization Code>"
 4vcdhost="<VCD Hostname>"
 5token="<VCD API Token String>"
 6
 7uri="https://$vcdhost/oauth/tenant/$org/token?grant_type=refresh_token&refresh_token=$token"
 8accesstok=`curl -s -k -X POST $uri -H "Accept: application/json" | jq -r '.access_token'`
 9headers=`curl -s -H "Accept: application/*+xml;version=36.1" -H "Authorization: Bearer $accesstok" -k -I -X GET https://$vcdhost/api/session`
10export VCD_TOKEN=`echo "$headers" | grep X-VMWARE-VCLOUD-ACCESS-TOKEN: | cut -f2- -d: | awk '{$1=$1};1'`

The easiest way to use this is to save as a shell script (and make executable) and then 'dot source' this . ./vcd-token.sh or source ./vcd-token.sh prior to applying any Terraform plan that requires the token to be set.

Note that this script uses jq to parse the initial returned JSON so this will need to be available in the environment too.

Hopefully will be useful to those of you looking to use the new VCD 10.3.1 API token system to replace stored credentials in your automation scripting.

Jon.