Cloud-init with Terraform in vSphere environment… last tip
As seen in my previous post, the “for-each” statement can be used by Terraform main and data to cycle on VM properties and properly fill the cloud-init templates transforming a single static declarative file, into a dynamic template that could be reused in a lot of cases.
During the Terraform execution probably you’ll see that the VM creation stops once the VM is simply created; only in the next 2-3 minutes (depending on the cloud-init and infrastructure), you will be able to interact with it, because the real machine setup ends with the end of cloud-init execution. How to address this situation, where the real VM setup must coincide with the end of the cloud-init setup and also with the end of Terraform execution?
The solution is very simple: since cloud-init comes with a CLI that owns a command to give the status of cloud-init execution (cloud-init status –wait), it’s possible to launch a terraform remote command that simply waits for the end of the user-data script. In a few words, simply add a “remote-exec” script inside the the “vsphere_virtual_machine” resources:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
resource vsphere_virtual_machine "allvms" { for_each = var.vms ... provisioner "remote-exec" { inline = [ "sudo cloud-init status --wait" ] connection { host = each.value.ip type = "ssh" user = each.value.user password = each.value.password } } |
The good thing is that the execution will end with an error in case of the cloud-init execution error. In this way, it’s possible to handle the VM execution addressing programmatically any state of VM creation.
I leave this post with the link of a real case on my public GitHub project here: https://github.com/linoproject/terraform/tree/master/rancher-lab