In a previous blog post I started to study Terraform, and how to connect it to vCloud Director. This time, I will build my entire lab using the same automation tool.
Networking
In any lab or production environment, we need to start from the ground: storage and networking. Since I’m using vCloud Director, the infrastructure is already taking care of the storage; so, I can immediately move to configuring networking.
For my Lab, I need a few organization networks, that would resemble my VLANs existing in the previous physical lab. The list is this:
NETWORK
|
VLAN
|
SUBNET
|
GATEWAY
|
dmz
|
111
|
10.10.111.0/24
|
10.10.111.254
|
management
|
51
|
10.10.51.0/24
|
10.10.51.254
|
storage
|
110
|
10.10.110.0/24
|
10.10.110.254
|
mpls
|
109
|
10.10.109.0/24
|
10.10.109.254
|
With these information, I can configure my networking template and feed Terraform with it. All the networks will be of the “Routed” type, as I will then use NSX Edge to manage traffic and firewalling between the different subnets.
# Step 1. Configure networking resource "vcd_network_routed" "vcc-management" { name = "vcc-management" edge_gateway = "VeeamLab_Edge" gateway = "10.10.51.254" netmask = "255.255.255.0" dns1 = "10.10.51.21" dns2 = "10.10.51.22" dns_suffix = "cloudconnect.local" dhcp_pool { start_address = "10.10.51.101" end_address = "10.10.51.120" } } resource "vcd_network_routed" "vcc-storage" { name = "vcc-storage" edge_gateway = "VeeamLab_Edge" gateway = "10.10.110.254" netmask = "255.255.255.0" dns1 = "10.10.51.21" dns2 = "10.10.51.22" dns_suffix = "cloudconnect.local" } resource "vcd_network_routed" "vcc-dmz" { name = "vcc-dmz" edge_gateway = "VeeamLab_Edge" gateway = "10.10.111.254" netmask = "255.255.255.0" dns1 = "10.10.51.21" dns2 = "10.10.51.22" dns_suffix = "cloudconnect.local" } resource "vcd_network_routed" "vcc-mpls" { name = "vcc-mpls" edge_gateway = "VeeamLab_Edge" gateway = "10.10.109.254" netmask = "255.255.255.0" dns1 = "10.10.51.21" dns2 = "10.10.51.22" dns_suffix = "cloudconnect.local" }
In less than a minute, all my networks are successfully created:
Catalogs
vCloud Director heavily relies on catalogs to automate vApp creation, and so does Terraform. A catalog, as the name implies, is a collection of vApp templates and/or Installation media that can be then used to automatically create new VMs and vApps. As the first step, we need to create a new catalog:
resource "vcd_catalog" "Install_media" { name = "Install_Media" description = "Catalog for files" delete_recursive = "true" delete_force = "true" }
Once we have a catalog, we upload our media files into it. For my lab, I need Windows 2016 and some Veeam installation files:
resource "vcd_catalog_media" "Windows2016" { catalog = "Install_Media" name = "Windows2016" description = "Windows 2016 Install ISO" media_path = "C:/downloads/en_windows_server_2016_x64_dvd_9327751.iso" upload_piece_size = 10 show_upload_progress = true } resource "vcd_catalog_media" "VeeamVAC" { catalog = "Install_Media" name = "Veeam_VAC_3.0" description = "Veeam Availability Console 3.0" media_path = "C:/downloads/VeeamAvailabilityConsole_3.0.0.2647.iso" upload_piece_size = 10 show_upload_progress = true } resource "vcd_catalog_media" "VeeamVBR" { catalog = "Install_Media" name = "Veeam_VBR_9.5.4a" description = "Veeam Backup E Replication 9.5 Update 4a" media_path = "C:/downloads/VeeamBackup_Replication_9.5.4.2753.Update4a.iso" upload_piece_size = 10 show_upload_progress = true }
When I apply the terraform plan, it tells me it’s going to upload the media:
And I can check the progress while it’s happening:
Note: in this screenshot you can see that the ISO file for Veeam Backup & Replication was uploaded. In reality, the first attempt failed, since Terraform doesn’t really like special characters like &. I renamed both the description and the ISO file before uploading it again. Also, avoid any space in the resource name.
Depending on the size of the files and the available bandwidth, this may take a while, but eventually the process will complete, and the files will be loaded into the catalog and ready to be used:
Uploading large files over public internet seems a bit unstable using vCloud director api, and so the upload process could fail, and in that case the media will be left in the catalog in a broken state. I found no way to resume the upload, so if we are stuck in a failed upload we need to manually delete the media from the catalog, and try again until the upload will eventually complete.
Templates
I also want to have a template to build quickly new virtual machines, and since Veeam software runs on Windows, I want to have a Windows 2016 template. Since i don’t have a template ready to be used, I tried to find a way to build one, but it came out that Terraform can only create VMs from templates, and not empty ones.
So, at least for the very first time, we need to build a new vApp/VM from scratch and later convert it to an OVA. Once the VM is completed, with all the settings and all the possible Windows updates installed, we just need to add it to our catalog:
and eventually also export it for future use, so that we can upload the template as we did for the ISO files before:
vApp and VMs
Now that we finally have a Windows 2016 template, we can build our vApps. First, we create the new empty vApps:
resource "vcd_vapp" "gateways" { name = "gateways" depends_on = ["vcd_network_routed.vcc-dmz"] } resource "vcd_vapp" "management" { name = "management" depends_on = ["vcd_network_routed.vcc-management"] } resource "vcd_vapp" "sobr" { name = "sobr" depends_on = ["vcd_network_routed.vcc-storage"] }
The three new vApps are quickly created:
We then add the first virtual machine:
resource "vcd_vapp_vm" "dc1" { vapp_name = "${vcd_vapp.management.name}" name = "dc1" catalog_name = "Install_Media" template_name = "Win2016DC" memory = 2048 cpus = 2 cpu_cores = 1 network { type = "org" name = "${vcd_network_routed.vcc-management.name}" ip = "10.10.51.21" ip_allocation_mode = "MANUAL" is_primary = true } depends_on = ["vcd_vapp.management"] }
At first, I found that the execution of the plan was failing because of a timeout of 1 minute:
Searching around, I learned that Terraform has a default timeout for operations of 1 minute. This is enough when we were creating small resources like a new network or a firewall rule, but it’s definitely not enough if we are building a virtual machine. So, we first add these lines into the variables:
variable "vcd_max_retry_timeout" { description = "vCloud Max Timeout" } provider "vcd" { max_retry_timeout = "${var.vcd_max_retry_timeout}"
And we then configure it to be 1800 seconds, that is 30 minutes:
vcd_max_retry_timeout = "1800"
Time to fire the plan again!
And here we go! With enough time, the VM creation is completed, and we can see it available in the selected vApp, with all the parameters we configured:
There is still a lot to do, since for example the vm name is still the one of the template, the password is auto-created, and other few glitches that I still don’t like. I will talk about these next steps in a third post, that’s all for now!