terraform-provider-vcd
terraform-provider-vcd copied to clipboard
Guest customization load order is not configurable to postcustomization
Hi there,
I want to run a guest customization script for a vcd_vm_app resource on launch. I wanted to make the script run post tools customization (e.g setting host name and IP address).
There seems to be support for this from VMware, although documentation is sparse on it: https://pubs.vmware.com/vcd-51/index.jsp#com.vmware.vcloud.users.doc_51/GUID-724EB7B5-5C97-4A2F-897F-B27F1D4226C7.html https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1026614
In a nutshell, there needs to be a wrapper around the script you are executing, defining which tasks are pre and post. I would want to execute my actions post (possible using this method).
However it seems, that the VCD provider picks up my actions by default as pre. This makes it impossible to use the network and the host name as they have not been set at that point yet. Here's some logs to show the behaviour:
DEBUG: Exit Code: 0
DEBUG: Command: 'hostname -f 2>/dev/null'
DEBUG: Result: localhost
DEBUG: Exit Code: 0
DEBUG: opening file /etc/sysconfig/network.
DEBUG: Match found : Line = HOSTNAME=localhost.localdomain
DEBUG: Actual String : localhost.localdomain
INFO: OLD HOST NAME = localhost.localdomain
INFO: Handling pre-customization ...
INFO: RunCustomScript invoked in '/tmp/.vmware-imgcust-d52grc3/' for 'precustomization'
DEBUG: Command: '/bin/cat /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat | /usr/bin/tr -d '^M' > /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat.tmp'
DEBUG: Result:
DEBUG: Exit Code: 0
DEBUG: Command: '/bin/mv -f /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat.tmp /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat'
DEBUG: Result:
DEBUG: Exit Code: 0
DEBUG: Command: '/bin/chmod u+x /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat'
DEBUG: Result:
DEBUG: Exit Code: 0
INFO: Executing pre-customization script...
INFO: precustomization
DEBUG: Command: '/bin/sh /tmp/.vmware-imgcust-d52grc3//script4204918823332955454.bat "precustomization"'
You can see in the above snippet, that it defaults to 'precustomization' even though that's not specified anywhere in my script.
The configuration is like this:
resource "vcd_vapp_vm" "repo" {
depends_on = ["vcd_vapp_vm.jump"]
provider = "vcd.xap"
vapp_name = "${vcd_vapp.xap_core.name}"
name = "repo01"
catalog_name = "${var.catalog_lin}"
template_name = "${var.template_lin}"
memory = 4096
cpus = 4
network_name = "${vcd_network.mgmt_net.name}"
ip = "${cidrhost(var.mgmt_network_ip_pool, 22)}"
initscript = "service network restart; cp -r /tmp/vm* /root/"
}
I have tested the script and it works if executed locally on post as root. I've also seen from the VMware logs that it does attempt to do actions defined in it, it just can't succeed due to no network.
I'm aware of the connection + remote-exec method, however I want to use clean API calls for this provisioning and according to documentation and manual test with the UI, this should be possible.
Can you please advise on how the initscript interacts with the API and if it's possible to override the precustomization
argument to postcustomization
?
Cheers
Have you tried wrapping your script with the IF statements as suggested in second link you posted?
#!/bin/sh
if [ x$1 == x"precustomization" ]; then
echo Do Precustomization tasks
elif [ x$1 == x"postcustomization" ]; then
echo Do Postcustomization tasks
fi
Yep that works, but there's one additional thing that might be needed in documentation to make it work: when I tried with raw input for initscript, it was not resolving linebreaks correctly and ultimately the script didn't run on the machines. I recommend adding this to the docs about initscript:
data "template_file" "myinitscript" {
template = "${file("${path.cwd}/mymagicinitscript.tpl")}"
vars {
x = "${var.from_varstf}"
y = "${var.from_varstf}"
}
}
resource "vcd_vapp_vm" "myvm" {
initscript = "${data.template_file.myinitscript.rendered}"
}
add a .tpl file in the same folder as the .tf file with this resource with the contents of the shell script:
#!/bin/bash
if [ x$1 == x"precustomization" ]; then
echo "Started doing pre-customization steps..."
echo "Finished doing pre-customization steps."
elif [ x$1 == x"postcustomization" ]; then
echo "Started doing post-customization steps..."
echo "Finished doing post-customization steps."
fi
if you can avoid it, don't add empty newlines in this .tpl file as it tends to break the script interpolation. Hope this is useful!
If you succeeded, you can find your script on the created VM under /root/.customization/custom* (don't exactly remember the filename). I also recommend adding logging to your script as the tools logging for these scripts is pretty bad. If you store credentials in your file, make sure you rm
the file in the end as it will stay on the disk if you don't!
Awesome - thanks for that. Shall tag this issue as a documentation update. Cheers! :)