terraform-provider-vcd
terraform-provider-vcd copied to clipboard
vcd_vapp_vm: recognize if the VM's power_on state has changed and reconcile
Affected Resource(s)
- vcd_vapp_vm
Terraform Configuration Files
resource "vcd_vapp_vm" "demo_vm_wordpress" {
vapp_name = vcd_vapp.demo_vapp.name
name = "demo-vm-wordpress"
catalog_name = "shared-catalog"
template_name = "bitnami-wordpress-5.3.2-2-r01-linux-centos-7-x86_64"
memory = 512
cpus = 1
power_on = true
network {
type = "org"
name = vcd_vapp_org_network.demo_vapp_net_org.org_network_name
ip_allocation_mode = "POOL"
is_primary = true
}
accept_all_eulas = "true"
}
Steps to Reproduce
- Power off the VM from VCD UI.
- Run
terraform plan
.
Expected Behavior
The plan should show that the actual VM is powered off and suggest to reconcile the state (power it back on).
Actual Behavior
Terraform doesn't notice the change in VM:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
References
Here's a similar example where it does work. Change VM CPU count in UI and run Terraform. It will reconcile the state:
# vcd_vapp_vm.demo_vm_wordpress will be updated in-place
~ resource "vcd_vapp_vm" "demo_vm_wordpress" {
accept_all_eulas = true
catalog_name = "shared-catalog"
computer_name = "bitnami-wordpress-532-2-r01-linux-centos-7-x8664-001"
cpu_cores = 1
cpus = 1
expose_hardware_virtualization = false
guest_properties = {
"demo.setting" = "Guest property set by Terraform vCD Provider"
}
hardware_version = "vmx-08"
href = "https://..."
id = "urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b"
internal_disk = [
{
bus_number = 0
bus_type = "parallel"
disk_id = "2000"
iops = 0
size_in_mb = 10240
storage_profile = "*"
thin_provisioned = true
unit_number = 0
},
]
memory = 512
metadata = {
"demo_data" = "Terraform vCD Provider"
}
name = "demo-vm-wordpress"
os_type = "otherLinux64Guest"
~ power_on = false -> true
storage_profile = "*"
template_name = "bitnami-wordpress-5.3.2-2-r01-linux-centos-7-x86_64"
vapp_name = "demo-web"
customization {
admin_password = (sensitive value)
allow_local_admin_password = true
auto_generate_password = true
change_sid = false
enabled = true
force = false
join_domain = false
join_org_domain = false
must_change_password_on_first_login = false
number_of_auto_logons = 0
}
network {
adapter_type = "VMXNET3"
ip = "192.168.0.2"
ip_allocation_mode = "POOL"
is_primary = true
mac = "00:50:56:29:00:04"
name = "demo-net-web"
type = "org"
}
}
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: yes
vcd_vapp_vm.demo_vm_wordpress: Modifying... [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b]
vcd_vapp_vm.demo_vm_wordpress: Still modifying... [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b, 10s elapsed]
vcd_vapp_vm.demo_vm_wordpress: Still modifying... [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b, 20s elapsed]
vcd_vapp_vm.demo_vm_wordpress: Still modifying... [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b, 30s elapsed]
vcd_vapp_vm.demo_vm_wordpress: Still modifying... [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b, 40s elapsed]
vcd_vapp_vm.demo_vm_wordpress: Modifications complete after 49s [id=urn:vcloud:vm:a60a0c5f-0498-4610-8f48-27c7c9de8f5b]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
The field power_on
is not state. It's a directive for create and update.
If we want to detect state, we need to add a new field state
(and eventually state_text
) as we did for vApp.
The reason for such implementation is that the "powered on" corresponds to several status codes. If we tie the current power_on
field to status 4 (= POWERED_ON) we will get a mismatch when the VM is in intermediate states that are not OFF, but not ON either, and we will have a request to update while the VM is reaching the online state.
This is a (possibly incomplete) list of the statuses available to vApp and VM
-1: "FAILED_CREATION",
0: "UNRESOLVED",
1: "RESOLVED",
2: "DEPLOYED",
3: "SUSPENDED",
4: "POWERED_ON",
5: "WAITING_FOR_INPUT",
6: "UNKNOWN",
7: "UNRECOGNIZED",
8: "POWERED_OFF",
9: "INCONSISTENT_STATE",
10: "MIXED",
11: "DESCRIPTOR_PENDING",
12: "COPYING_CONTENTS",
13: "DISK_CONTENTS_PENDING",
14: "QUARANTINED",
15: "QUARANTINE_EXPIRED",
16: "REJECTED",
17: "TRANSFER_TIMEOUT",
18: "VAPP_UNDEPLOYED",
19: "VAPP_PARTIALLY_DEPLOYED",
If we map 1-to-1 the power_on
field to the VM status, most likely we get a state comparison failure, because the VM could be in an intermediate state before reaching the wanted one. Notice that the status field is overloaded by meanings that have nothing to do with the VM being online or not.
This is not similar to what happens when we modify,, say, the amount of memory. If we change the memory outside of Terraform, at the next read we will get the exact memory that is now assigned, not an intermediate value, and a reconciliation is immediately possible.
With the VM status, this is not feasible. If we make, for example, a wanted_status="POWERED_ON"
, the state comparison will return an error if the status is in an intermediate phase, meaning that it will eventually be online, but not just yet. If we act on such state discrepancy and try to force a power on operation, we would get a further error because we can't power on an already online VM.
I suggest two actions:
- add the fields
status
andstatus_text
like we have in vApp - Possibly improve the wording of the documentation to explain that
power_on
does not collect state, but is only a request for action.