В статье Terraform + vRA. Быстрый старт новый деплоймент создаётся из опубликованного в каталоге vRA элемента. Это самый простой способ работы с vRA из Terraform, но он недостаточно гибкий, — нет возможности изменить схему шаблона, деплойменты будут такими, как решил администратор Cloud Assembly. Terraform позволяет создавать свои облачные шаблоны и разворачивать из них деплойменты.
Terraform предлагает два способа работы с облачными шаблонами vRA 8 (раньше они назывались блюпринтами).
Динамическое описание шаблона из Terraform
Облачный шаблон генерируется на лету в процессе развертывания инфраструктуры через Terraform:
# main.tf
provider "vra" {
url = var.url
refresh_token = var.refresh_token
insecure = var.insecure
}
data "vra_project" "this" {
name = var.project_name
}
resource "random_id" "this" {
byte_length = 4
}
resource "vra_blueprint" "this" {
name = "${var.blueprint_name} (${random_id.this.hex})"
description = "Created by vRA terraform provider"
project_id = data.vra_project.this.id
content = <<-EOT
formatVersion: 1
inputs:
vmCount:
type: integer
minimum: 1
maximum: 5
vmSize:
type: string
title: VM size
enum:
- micro
- small
- medium
- large
default: small
imageName:
type: string
enum:
- CentOS_7
- CentOS_8
- Debian_9
- Ubuntu_16
- Ubuntu_18
- Windows_2012
- Windows_2016
default: CentOS_7
description: OS type
resources:
Cloud_Network_1:
type: Cloud.Network
properties:
networkType: existing
Cloud_vSphere_Machine_1:
type: Cloud.vSphere.Machine
properties:
count: '$${input.vmCount}'
image: '$${input.imageName}'
flavor: '$${input.vmSize}'
cloudConfig: null
name: 'vra-tf'
customizationSpec: '$${starts_with(input.imageName, "Windows") ? "tmp-windows-vra" : "tmp-linux-vra"}'
networks:
- network: '$${resource.Cloud_Network_1.id}'
assignment: static
EOT
}
data "vra_blueprint" "this" {
name = vra_blueprint.this.name
depends_on = [vra_blueprint.this]
}
resource "vra_blueprint_version" "this" {
blueprint_id = data.vra_blueprint.this.id
change_log = "First version"
description = "Released from vRA terraform provider"
release = true
version = "1.0.1"
}
resource "vra_deployment" "this" {
name = "${var.deployment_name} - ${random_id.this.hex}"
description = var.deployment_descr
project_id = data.vra_project.this.id
blueprint_id = data.vra_blueprint.this.id
blueprint_version = "1.0.1"
inputs = {
vmCount = var.vm_count
vmSize = var.vm_flavor
imageName = var.image
}
timeouts {
create = "60m"
delete = "20m"
update = "30m"
}
}
Все файлы доступны для загрузки на https://github.com/isas2.
В данном примере создаётся новый шаблон и получается его ID, код шаблона задаётся в параметре content, далее из шаблона разворачивается деплоймент. Обратите внимание, что переменные внутри кода шаблона экранированы дополнительным символом '$'.
Если позднее изменить этот шаблон (через Terraform или веб-интерфейс), то обновления развернутых из него деплойментов не произойдёт, обновится только сам облачный шаблон. Для применения обновлений используйте описание версии шаблона: resource "vra_blueprint_version". Также рекомендую все возможные параметры шаблонов выносить во входные параметры. Изменение значений входных параметров и номера версии шаблона в описании деплоймента приводит к его перенастройке.
Использование vra_blueprint имеет явное преимущество по сравнению с развёртываниями из элементов каталога: пользователь получает больше свободы, он самостоятельно описывает состав и параметры своих шаблонов.

Использование готовых шаблонов vRA
Описание шаблона внутри конфигурации Terraform сильно усложняет её код. Использование готовых облачных шаблонов - более удобный способ работы.
# main.tf
provider "vra" {
url = var.url
refresh_token = var.refresh_token
insecure = var.insecure
}
data "vra_project" "this" {
name = var.project_name
}
resource "random_id" "this" {
byte_length = 4
}
data "vra_blueprint" "this" {
name = var.blueprint_name
}
resource "vra_deployment" "this" {
name = "${var.deployment_name} - ${random_id.this.hex}"
description = var.deployment_descr
project_id = data.vra_project.this.id
blueprint_id = data.vra_blueprint.this.id
blueprint_version = var.blueprint_version
inputs = {
vmCount = var.vm_count
vmSize = var.vm_flavor
imageName = var.image
}
timeouts {
create = "60m"
delete = "20m"
update = "30m"
}
}
output "addresses_by_vmname" {
description = "VM name and IP addresses from a vRA deployment"
value = {
for props in vra_deployment.this.resources.*.properties_json :
jsondecode(props).resourceName => jsondecode(props).address
if try(jsondecode(props).componentType, "") == "Cloud.vSphere.Machine"
}
}
output "resource_properties_by_name" {
description = "Properties of all resources by its name from a vRA deployment"
value = {
for rs in vra_deployment.this.resources :
rs.name => jsondecode(rs.properties_json)
}
}
Все файлы доступны для загрузки на https://github.com/isas2.
В данном примере в код добавлены выходные параметры Terraform:
- addresses_by_vmname после выполнения будет содержать имена всех VM и их IP-адреса:
addresses_by_vmname = {
"vra-tf-752" = "192.168.203.45"
"vra-tf-753" = "192.168.203.44"
}
- resource_properties_by_name - содержит свойства всех ресурсов деплоймента.
Внимание! Для работы приведённых примеров пользователю vRA потребуются роли "Service Broker User" и "Cloud Assembly User".
Если необходимо генерировать облачные шаблоны на лету, не перегружая ими код Terraform, то vRA 8 умеет использовать GitLab в качестве внешнего хранилища шаблонов. При работе с GitLab Вам могут пригодиться следующие REST-запросы:
- /content/api/sourcecontrol/sync-all-requests - синхронизация всех внешних источников для данного проекта(-ов);
- /content/api/sourcecontrol/sync-requests - синхронизация одного источника данных;
- /content/api/sourcecontrol/sync-requests/{id} - получение статуса синхронизации по её ID. Возвращаемые значения статуса: "REQUESTED", "STARTED", "PROCESSING", "COMPLETED", "FAILED", "SKIPPED".