Add Cloud Account in Aria Automation using API

Last modified date

Since I am deploying new releases of Aria Automation often, I wanted to automate the configuration as much as possible with the tool of my choice Powershell. One of the first things you want to configure after you have deployed Aria Automation is a Cloud Account and a Cloud Zone; in my case a vSphere Cloud Account.

From the API Documenation and Swagger UI, you can see that there are 2 API’s to create a Cloud Account:

  • /iaas/api/cloud-accounts
  • /iaas/api/cloud-account-vsphere

I chose to use the /iaas/api/cloud-account-vsphere API. It turned out to be quite challenging sometimes  which mostly had to do with finding the correct Id’s and notation in the JSON data.

In vCenter I have a Datacenter object called “dc-mgmt” with two clusters “cls-mgmt” and “cls-work”. My goal is to automate the creation of a Cloud Account with a Cloud Zone including only the cls-mgmt Cluster.

The script starts with defining the variables:

#vCenter (to add to vRA as CloudAccount) VARIABLES
$vcenterName = "vcsamgmt"
$vcenterHostname = $vcenterName+"."+$domain
$vcenterUsername = "administrator@vsphere.local"
$vcenterPassword = "VMware1!"
$vcenterDatacenter = "dc-mgmt" #Name of the vCenter datacenter object to add
$vcenterCluster = "cls-mgmt"
$vcenterDeploymentFolder = "vRADeployments"

#vRA VARIABLES
$vraName = "vra"
$domain = "infrajedi.local"
$vraHostname = $vraname+"."+$domain
$vraUsername = "configadmin"
$vraPassword = "VMware1!" #note use ` as escape char for special chars like $
$vraUserDomain = "System Domain" #Use "System Domain" for local users", otherwise use the AD domain.

After the variable are set, connect to your vCenter to retrieve the vCenter Datacenter Id which is stored in the $vcenterDatacenterID variable.

#Connect to vCenter to retrieve the datacenter id Connect-VIServer
$vcenterHostname -User $vcenterUsername -Password $vcenterPassword
$vcenterDatacenterId = (get-datacenter "$vcenterDatacenter" |Select Id).Id

#Results in Datacenter-datacenter-2 format, should be in Datacenter:datacenter-2 format for vRA 
[regex]$pattern = "-" 
$vcenterDatacenterIdFormatted = $pattern.Replace($vcenterDatacenterId, ":", 1)
DisConnect-VIServer $vcenterHostname -Confirm:$false

The value for $vcenterDatacenterID is Datacenter-datacenter-2. However, for the body of the API call we are going to use, this value needs to be formatted in another way; the first “-“ has to be replaced by “:”. The replace method in the script takes care of that and a new variable $vcenterDatacenterIdFormatted is created. The value for $vcenterDatacenterIdFormatted is Datacenter:datacenter-2.

Retrieving API tokens to login to vRA is described in a previous blogpost, so I’ll skip that part and go to the code I use to create the Cloud Account:

####################################
#   Create vCenter Cloud Account   #
####################################
$vCenterJSON = @"
{
  "hostName": "$vcenterHostname",
  "username": "$vcenterUsername",
  "password": "$vcenterPassword",
  "acceptSelfSignedCertificate": true,
  "createDefaultZones": false,
  "regions": [
    {
      "name": "$vcenterDatacenter",
      "externalRegionId": "$vcenterDatacenterIdFormatted"
    }
  ],
  "name": "$vcenterName",
  "description": "$vcenterName Cloud Account"
}
"@
$uri = "https://$vraHostname/iaas/api/cloud-accounts-vsphere"
try {
    $vCenterCloudAccount = Invoke-RestMethod -Method Post -Uri $uri -Headers $header -Body $vCenterJSON
} catch {
    write-host "Failed to create Cloud Account on host: $vraHostname" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}

The regions part in the JSON body of the parsed script looks like this:

    "regions": [
      {
        "name": "dc-mgmt",
        "externalRegionId": "Datacenter:datacenter-2"
      }
    ],
  • Note: Setting createDefaultZones to true will create a Cloud Zone containing all resources (clusters) from the Cloud Account and this is not my goal. It might be yours, so set it to true in that case.

If you want to create a Cloudzone manually, you need to retrieve the Region Id and depending on your goal also the Fabric Id. Since I only have one Region, the below scriptpart will do the job to retrieve the Region Id.

# Get RegionId
$response=""
$uri = "https://$vraHostname/iaas/api/regions"
try {
    $response = Invoke-RestMethod -Method Get -Uri $uri -Headers $header
} catch {
    write-host "Failed to retreive Regions" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}
$regionId = $response.content.id

The variable $regionId will be used in the follow up scriptparts. The regionId has the following format:

"regionId": "7795b0aa-8502-42ad-9564-8097c8569999",

Three options to add compute to create Cloudzones

There are three options to add compute to a cloudzone which are discussed below.

Create Cloudzone with all unassigned compute from the Cloud Account

This is the easiest method. You might as well have used the createDefaultZones parameter set to true. Adding it manually however offers you some additional options like settings tags, custom properties and choosing a Virtual machine Folder, Placement Policy.

##################################################
# Create Cloud Zone - Option 1                   #
# including all clusters from vSphere datacenter #
##################################################
# tags the Cloud Zone (example)
$cloudzoneName = "cz-mgmt"
$cloudZoneDescription = "Cloudzone for $cloudzoneName"
$cloudzoneJSON = @"
{
    "name": "$cloudzoneName",
    "description": "$cloudZoneDescription",
    "regionId": "$regionId",
    "tags": [
        {
            "key": "cz",
            "value": "mgmt"
        }
    ],
    "folder": "$vcenterDeploymentFolder",
    "placementPolicy": "DEFAULT"
}
"@
$uri = "https://$vraHostname/iaas/zones"
try {
    $cloudZone = Invoke-RestMethod -Method Post -Uri $uri -Headers $header -Body $cloudzoneJSON
} catch {
    write-host "Failed to create Cloudzone $cloudzoneName" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}

Create Cloudzone with compute selected dynamically based on tags

If you do not have tags setup on your Cluster in vCenter, you can create vRA Tags with the following script part. This includes the retrieval of the Fabric Id and storing it in the $fabricId variable.

# If you did not set tags in vCenter on the cluster, you can set tags in vRA.
# First Get vSphere Cluster (Fabric Computes) id by name
$uri = "https://$vraHostname/iaas/api/fabric-computes?`$filter=name eq '$vcenterCluster'"
try {
    $response = Invoke-RestMethod -Method Get -Uri $uri -Headers $header
} catch {
    write-host "Failed to retrieve clusters" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}
$response.content
$fabricExternalId = $response.content.externalId
$fabricId = $response.content.id

After the FabricId is retrieved you can set the tags on the Cluster:

# Tag a vSphere Cluster in Aria Automation
$clusterTagJSON =@"
{
    "tags": [
        {
            "key": "cz",
            "value": "mgmt"
        }
    ]
}
"@
$uri = "https://$vraHostname/iaas/api/fabric-computes/$fabricId"
try {
    $response = Invoke-RestMethod -Method Patch -Uri $uri -Headers $header -Body $clusterTagJSON
} catch {
    write-host "Failed to set Tags on Cluster: $clusterName" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}

After the tags have been set, you can now create the tag based Cloudzone.

  • Note the tagsToMatch entry that does the magic here.
# Create the Tag based Cloudzone
$cloudzoneName = "cz-mgmt"
$cloudZoneDescription = "Cloudzone for $cloudzoneName"
$cloudzoneJSON = @"
{
    "name": "$cloudzoneName",
    "description": "$cloudZoneDescription",
    "regionId": "$regionId",
	"tagsToMatch": [
		{
		  "key": "cz",
		  "value": "mgmt"
		}
	  ],
	"folder": "$vcenterDeploymentFolder",
    "placementPolicy": "DEFAULT"
}
"@
$uri = "https://$vraHostname/iaas/zones"
try {
    $cloudZone = Invoke-RestMethod -Method Post -Uri $uri -Headers $header -Body $cloudzoneJSON
} catch {
    write-host "Failed to create Cloudzone $cloudzoneName" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}

Create Cloudzone with manual selected compute from the Cloud Account

For this method, you also need to retrieve the Fabric Id first. For convenience I have included this part again.

##################################################
# Create Cloud Zone - Option 3                   #
# Manually include compute by tags on Cluster    #
##################################################
# First Get vSphere Cluster (Fabric Computes) id by name
$uri = "https://$vraHostname/iaas/api/fabric-computes?`$filter=name eq '$vcenterCluster'"
try {
    $response = Invoke-RestMethod -Method Get -Uri $uri -Headers $header
} catch {
    write-host "Failed to retrieve clusters" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}
$fabricId = $response.content.id

$cloudzoneName = "cz-mgmt"
$cloudZoneDescription = "Cloudzone for $cloudzoneName"
$cloudzoneJSON = @"
{
    "name": "$cloudzoneName",
    "description": "$cloudZoneDescription",
    "regionId": "$regionId",
    "tags": [
        {
            "key": "cz",
            "value": "mgmt"
        }
    ],
    "placementPolicy": "DEFAULT",
    "folder": "$vcenterDeploymentFolder",
    "computeIds": [$fabricId]
}
"@
$uri = "https://$vraHostname/iaas/zones"
try {
    $cloudZone = Invoke-RestMethod -Method Post -Uri $uri -Headers $header -Body $cloudzoneJSON
} catch {
    write-host "Failed to create Cloudzone $cloudzoneName" -ForegroundColor red
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    break
}

Note: for some reason I struggled with the notation for computeIds. The parsed JSON looks like this:

{
    "name": "cz-mgmt",
    "description": "Cloudzone for cz-mgmt",
    "regionId": "7795b0aa-8502-42ad-9564-8097c8569999",
    "tags": [
        {
            "key": "cz",
            "value": "mgmt"
        }
    ],
    "placementPolicy": "DEFAULT",
    "folder": "vRADeployments",
    "computeIds": [7c40d2a5-34e2-459c-a9dc-982ea0edc9c8]
}

That’s it. Hope this was helpful. You can find the script (vRA8-CloudAccounts-Zones.ps1) on my github page along with some other examples.

Henk Engelsman