The article Terraform + vRA. Quickstart a new deployment is created from an item published in the vRA directory. This is the easiest way to work with vRA from Terraform, but it is not flexible enough – there is no way to change the template schema, the deployments will be the same as the Cloud Assembly administrator decided. Terraform allows you to create your own cloud templates and deploy deployments from them.
Terraform offers two ways to work with vRA 8 cloud templates (formerly called blueprints).
Dynamic template description from Terraform
The cloud template is generated on the fly during infrastructure deployment via 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" } }
All files are available for download at https://github.com/isas2.
In this example, a new template is created and its ID is obtained, the template code is set in the content parameter , then the deployment is expanded from the template. Note that variables inside the template code are escaped with an extra ‘ $ ‘ character .
If you later change this template (via Terraform or the web interface), then deployments deployed from it will not be updated, only the cloud template itself will be updated. To apply updates, use the description of the template version: resource “vra_blueprint_version” . I also recommend putting all possible template parameters into input parameters. Changing the values of the input parameters and the version number of the template in the deployment description leads to its reconfiguration.
Using vra_blueprint has a clear advantage over deployments from catalog items : the user gets more freedom, he independently describes the composition and parameters of his templates.
Using out-of-the-box vRA templates
Describing a template within a Terraform configuration makes the code very complex. Using ready-made cloud templates is a more convenient way to work.
# 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" } }
All files are available for download at https://github.com/isas2.
This example adds Terraform output parameters to the code:
- addresses_by_vmname after execution will contain the names of all VMs and their IP addresses:
addresses_by_vmname = {
"vra-tf-752" = "192.168.203.45"
"vra-tf-753" = "192.168.203.44"
}
- resource_properties_by_name – contains properties of all deployment resources.
Attention! For these examples to work, the vRA user will need the “Service Broker User” and “Cloud Assembly User” roles.
If you need to generate cloud templates on the fly without overloading Terraform code with them, then vRA 8 can use GitLab as an external template repository. When working with GitLab, you might find the following REST requests useful:
- / content / api / sourcecontrol / sync-all-requests – synchronization of all external sources for this project (s);
- / content / api / sourcecontrol / sync-requests – synchronization of one data source;
- / content / api / sourcecontrol / sync-requests / {id} – getting the sync status by its ID. Returned status values: “REQUESTED”, “STARTED”, “PROCESSING”, “COMPLETED”, “FAILED”, “SKIPPED”.
Translated by Google Translate