HashiCorp Terraform vCloud Director Provider v2.5.0 version is here! With this new release we’re enabling cloud providers and their customers deliver more advanced automation with new data sources and import capabilities, which enable easy inclusion of existing vCD resources into Terraform management. We have also extended read functionality, which enables monitoring changes done to infrastructure, added a new kind of NAT and firewall resources for advanced security automation and various other improvements. Finally, this v2.5.0 release adds support for the latest vCloud Director 10.0 version. So, let’s take a deeper look at the key new capabilities.
New Data Sources
In this version we have added a raft of data sources. Data sources are really cool, as they allow you to query details about resources which have been created by means other than Terraform (like through UI) or by other users (if permissions allow, of course).
Here’s an example where we query an existing external network and use its IP address to create a DNAT rule:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Query existing resource data "vcd_external_network" "demo-ext-net" { name = "demo-ext-net" } resource "vcd_nsxv_dnat" "demo_dnat_wordpress_https" { edge_gateway = "${vcd_edgegateway.demo_gw.name}" network_type = "ext" network_name = "demo-ext-net" // Use IP address from the queried data source original_address = "${data.vcd_external_network.demo-ext-net.ip_scope[0].static_ip_pool[0].start_address}/32" original_port = 4443 translated_address = "${vcd_vapp_vm.demo_vm_wordpress.network[0].ip}/32" translated_port = 443 protocol = "tcp" } |
Almost all resources have their corresponding data sources now! Here’s a full list. As you can see only VM is missing (which we’re adding to the next release):
Reads for Resource Parameters
Together with data sources, we have added read functionality to most of the resources’ properties. These reads take place during a state refresh (say, when running terraform plan
or terraform apply
). With these reads in place, Terraform “notices” changes which have been made to infrastructure without its knowledge.
For instance, if we go to UI and change the above DNAT rule’s translated_port
from 443
to 1000
and run Terraform, we will get a notification about such discrepancy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
$ terraform apply vcd_nsxv_dnat.demo_dnat_wordpress_ssh: Refreshing state... [id=196614] An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # vcd_nsxv_dnat.demo_dnat_wordpress_https will be updated in-place ~ resource "vcd_nsxv_dnat" "demo_dnat_wordpress_https" { edge_gateway = "demo-gw" enabled = true id = "196613" logging_enabled = false network_name = "demo-ext-net" network_type = "ext" original_address = "10.150.160.116/32" original_port = "4443" protocol = "tcp" rule_tag = "196613" rule_type = "user" translated_address = "192.168.0.2/32" ~ translated_port = "1000" -> "443" } Plan: 0 to add, 1 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: |
As a user you can now decide whether to:
a. Re-apply the value that is in HCL file to vCD (by answering “yes”).
b. Manually adjust the HCL file with the new read value from vCD and rerun the plan.
Migrate Existing Resources with Imports
We have also added import capabilities for migrating existing resources into Terraform management.
Say, we have a firewall rule in UI, but we don’t have it in Terraform configuration file yet:
With v2.5.0 we can import it into the state file, which will make it straightforward to write it up in the configuration for further management via Terraform.
First, let’s define a placeholder resource in the HCL file with the known field values filled in:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
resource "vcd_nsxv_firewall_rule" "imported" { org = "demo-org" vdc = "demo-vdc" edge_gateway = "demo-gw" name = "" source { ip_addresses = [] } destination { ip_addresses = [] } service { protocol = "" port = "" source_port = "" } } |
And let’s run a tailored terraform import
command telling into which resource to import the above UI rule:
1 2 3 4 5 6 7 8 9 10 |
$ terraform import vcd_nsxv_firewall_rule.imported demo-org.demo-vdc.demo-gw.ui-no.3 vcd_nsxv_firewall_rule.imported: Importing from ID "demo-org.demo-vdc.demo-gw.ui-no.3"... vcd_nsxv_firewall_rule.imported: Import complete! Imported vcd_nsxv_firewall_rule vcd_nsxv_firewall_rule.imported: Refreshing state... [id=131093] Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform. |
We now have this resource in the state file with all its imported values. Let’s run terraform plan
which will show us the differences compared to contents in the HCL file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
$ terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. vcd_nsxv_firewall_rule.imported: Refreshing state... [id=131093] ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # vcd_nsxv_firewall_rule.imported will be updated in-place ~ resource "vcd_nsxv_firewall_rule" "imported" { action = "accept" edge_gateway = "demo-gw" enabled = true id = "131093" logging_enabled = false - name = "ui-created-rule" -> null org = "demo-org" rule_tag = "131093" rule_type = "user" vdc = "demo-vdc" ~ destination { exclude = false gateway_interfaces = [] ~ ip_addresses = [ - "10.150.160.116", ] org_networks = [] virtual_machine_ids = [] } - service { - port = "8081" -> null - protocol = "tcp" -> null - source_port = "any" -> null } + service { + port = (known after apply) + source_port = (known after apply) } source { exclude = false gateway_interfaces = [] ip_addresses = [] org_networks = [] virtual_machine_ids = [] } } Plan: 1 to add, 0 to change, 1 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run. |
Let’s copy/paste the relevant required values from the plan where it shows minuses to our configuration until terraform plan
becomes “happy” and shows no differences.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
resource "vcd_nsxv_firewall_rule" "imported" { org = "demo-org" vdc = "demo-vdc" edge_gateway = "demo-gw" name = "ui-created-rule" source { ip_addresses = [] } destination { ip_addresses = ["10.150.160.116"] } service { protocol = "tcp" port = "8080" source_port = "any" } } |
If we run the plan again, it will report no changes, because values in the state and the HCL files match:
1 |
Plan: 0 to add, 0 to change, 0 to destroy. |
We can now make changes to this resource in Terraform configuration file and manage it as the usual Terraform resources!
For more general information about importing please see Terraform documentation.
New NSX-V DNAT, SNAT and Firewall Rules
You may have noticed that in the examples above the NAT and FW rule resources are different from the ones in previous versions. What we have done here is added new DNAT, SNAT and FW rule resources for Advanced Edge Gateways, which use NSX-V API (through a proxy in vCD API) as opposed to the older vCD API calls.
These new resources should always be used if your Edge Gateway is of Advanced (NSX-V) type.
Upgrade Note
Please note that in an effort to make the provider more robust, we have systematically changed resource identifiers in the state file to vCD IDs where names were used.
Here’s an example of a Catalog Item (please note the new long “urn:…” value in the “id” field):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
"resources": [ { "mode": "data", "type": "vcd_catalog_item", "name": "catalog-item", "provider": "provider.vcd", "instances": [ { "schema_version": 0, "attributes": { "catalog": "shared-catalog", "description": "", "id": "urn:vcloud:catalogitem:e38293ff-d74f-4f68-a128-e1b099eb88f7", "metadata": {}, "name": "bitnami-wordpress-5.2.2-3-linux-centos-7-x86_64", "org": "shared-catalog" } } ] }, |
When you upgrade from v2.4.0 to v2.5.0, in some cases this change may result in terraform plan
asking to recreate a resource. In case this occurs, please see a new troubleshooting page where we describe how to use the import functionality to resolve it.
By the way, if you’d also like to learn more about the previous v2.4.0 release, please click here.
Other Improvements
Of course, as usual, we have added many other improvements and bug fixes too. Thank you for the community users who took time to publish issues hit and features needed – please keep the feedback coming!
Here are some of these items:
- Add support for vCD 10.0
- Drop support for vCD 8.20
vcd_vapp
– Add propertiesstatus
andstatus_text
vcd_vapp_vm
– Allow to force guest customizationvcd_vapp
andvcd_vapp_vm
– Support guest propertiesvcd_network_direct
– Add computed properties (external network gateway, its netmask, DNS and DNS suffix)vcd_vapp_vm
– New fieldcomputer_name
vcd_independent_disk
– Add computed properties (iops
,owner_name
,datastore_name
,is_attached
)vcd_catalog_media
– Add computed properties (is_iso
,owner_name
,is_published
,creation_date
,size
,status
,storage_profile_name
)
For a full list of additions and fixes, please see the v2.5.0 changelog.
And, most importantly, please give the new Terraform vCloud Director Provider a try! By the way, you can always reach us via GitHub or Slack #vcd-terraform-dev channel which you can join through VMware {code}.