VMware vCloud Director REST API with Terraform

Overview

If you work with VMware vCloud Director (vCD) and Terraform regularly, you're likely familiar with the vcd provider for interacting with the vCD API. This provider is an excellent tool for automating the deployment of vCD resources and managing the lifecycle of your virtual datacenters.

However, you may have noticed some limitations in the vcd provider, particularly when it comes to managing infrastructure components. To handle these components with Terraform, you will need to interact directly with the vCD REST API. In this post, I'll share how I approach this specific use case.

Terraform providers

In this particular situation I use the following providers:

 1terraform {
 2  required_version = ">= 1.6"
 3  required_providers {
 4    vcd = {
 5      source  = "vmware/vcd"
 6    }
 7    restful = {
 8      source = "magodo/restful"
 9    }
10  }
11}
  • The vmware/vcd provider is the official VMware provider for vCloud Director. We will use it to retrieve a refresh token that we will use to authenticate to the vCD API.
  • The magodo/restful will provide a simple way to authenticate using the refresh token with oauth2 and to run requests over the REST API of vCloud.

Authentication process

vCD provider configuration

With a set of variables to define URI, credentials, and other parameters, we can configure the vCD provider for the System Org.

 1# Configure the VMware Cloud Director Provider for the System Org
 2provider "vcd" {
 3  alias                = "vcd-sys"
 4  user                 = var.vcloud_admin_username
 5  password             = var.vcloud_admin_password
 6  auth_type            = "integrated"
 7  org                  = "System"
 8  url                  = "${var.vcloud_uri}/api"
 9  max_retry_timeout    = 30
10  allow_unverified_ssl = var.vcloud_insecure
11}

Refresh token generation

vmware/vcd provider provides a vcd_api_token resource that allows you to create a refresh token that you can use to authenticate to the vCD API to generate a bearer token.

The refresh_token will be stored in a file to be reused by the next provider.

 1# Create a refresh token
 2resource "vcd_api_token" "vcd_sys" {
 3  provider         = vcd.vcd-sys
 4  name             = "vcd-sys"
 5  file_name        = ".vcd-sys-token.json"
 6  allow_token_file = true
 7}
 8
 9# Load refresh token file
10data "local_file" "vcd_sys_token" {
11  filename = vcd_api_token.vcd_sys.file_name
12}

restful provider configuration

In this step, we will use the magodo/restful provider and specify the refresh_token information to configure a oauth2.refresh_token section.

I provided an alias name to this provider in order to be able to dissociate sysadmin tasks and normal users ones.

 1# Create a vcd provider with the refresh token
 2provider "restful" {
 3  alias    = "vcd-sys"
 4  base_url = var.vcloud_uri
 5  security = {
 6    oauth2 = {
 7      refresh_token = {
 8        token_url     = "${var.vcloud_uri}/oauth/provider/token"
 9        refresh_token = jsondecode(data.local_file.vcd_sys_token.content)["refresh_token"]
10      }
11    }
12  }
13  header = {
14    "Accept"       = "*/*;version=${var.vcloud_api_version}",
15    "Content-Type" = "application/json"
16  }
17  client  = {
18    tls_insecure_skip_verify = var.vcloud_insecure
19  }
20}

Objects management through the REST API

We can now use the above provider and the restful_operation resource to create objects by using the REST API, like the creation of a vCenter Server object to associate with the vCloud Director instance:

 1resource "restful_operation" "register_avs_vcenter" {
 2  provider = restful.vcd-sys
 3  path     = "/cloudapi/1.0.0/virtualCenters"
 4  method   = "POST"
 5  data     = jsonencode({
 6    "vcId" : null,
 7    "name" : "vCenter01",
 8    "description" : "vCenter01 resources",
 9    "username" : var.vcenter_username,
10    "password" : var.vcenter_password,
11    "url" : var.vcenter,
12    "isEnabled" : true,
13    "vsphereWebClientServerUrl" : null,
14    "hasProxy" : false,
15    "rootFolder" : null,
16    "vcNoneNetwork" : null,
17    "vcNoneNetworkMoref" : null,
18    "tenantVisibleName" : null,
19    "isConnected" : true,
20    "mode" : "NONE",
21    "listenerState" : "INITIAL",
22    "clusterHealthStatus" : "GRAY",
23    "vcVersion" : null,
24    "buildNumber" : null,
25    "uuid" : "${var.vcenter}/sdk",
26    "nsxVManager" : null,
27    "proxyConfigurationUrn" : null
28  })
29}

Conclusion

The example above demonstrates a scenario where the vmware/vcd provider lacks the necessary functionality to manage certain objects. In such cases, the vCD REST API can be used to manage these objects and automate the deployment of vCD resources.

However, it's important to note that the vCD REST API is not as user-friendly as the vmware/vcd provider and does not provide sufficient abstraction for managing other lifecycle operations like updates and deletes without significant effort. Therefore, it is recommended to use the vCD REST API only when necessary and to rely on the vmware/vcd provider for most operations.