Pozn.: Popis v článku vychází z Terraform verze 1.14.4, VMware Cloud Director Provider verze 3.14 a VMware Cloud Director 10.6.
VM Guest OS Customization
Guest OS Customization je funkce VMware Cloud Director, která umožňuje přizpůsobit (konfigurovat) některá nastavení hostovaného operačního systému. Používá se pro VM, která vytvoříme ze šablony. Konfigurace probíhá při prvním bootu VM nebo pokud nastartujeme VM s volbou Power on, Force Recustomization. Využívají se VMware Tools. Cloud Director vytvoří balíček, který zkopíruje, spustí a odstraní z VM, když probíhá přizpůsobení.
Můžeme nastavit hostname, síťové parametry, změnit SID a zařadit do domény (pro Windows), nastavit heslo administrátora či spustit zadaný skript. Právě možnosti spustit vlastní skript v OS virtuálního stroje se věnujeme v tomto článku. Skript má omezení na maximální délku 1500 znaků.
Guest Customization musí být povolena, aby mohla proběhnout. Při zapnutí VM by mělo proběhnout nastavení názvu počítače a síťových parametrů. Toto nastavení nemůžeme vypnout, pokud chceme přizpůsobení povolit. Při prvním zapnutí (nebo vynucení) probíhá ostatní nastavení, včetně spuštění skriptu. Doporučuje se po prvním aplikování přizpůsobení vypnout.
Pozn.: Pro přizpůsobení můžeme u VM využít ještě Guest Properties. Tyto dvě možnosti bychom neměli kombinovat.
Terraform VMware Cloud Director Provider
Vyjdeme z příkladu, popsaného v minulém článku, na vytvoření nového VM ze šablony pomocí Terraform a VMware Cloud Director Provider. Některé hodnoty, které jsme zadali přímo do konfigurace, nyní nahradíme proměnnými.
Do souboru variables.tf přidáme definice nových proměnných.
# VM parameters
variable "vm_name" {
type = string
}
variable "vm_ip" {
type = string
}
variable "vm_ip_mask" {
type = string
}
variable "vm_gw" {
type = string
}
variable "vm_dns" {
type = string
}
V souboru terraform.tfvars nastavíme jejich hodnoty.
# VM parameters
vm_name = "Demo-VM"
vm_ip = "172.30.21.100"
vm_ip_mask = "22"
vm_gw = "172.30.20.1"
vm_dns = "172.30.20.1"
Vytvoření VM a nastavení přizpůsobení (blok customization)
V prostředku vcd_vapp_vm můžeme použít blok customization, kde nastavujeme parametry Guest OS Customization.
# create VM from template wtih manual IP assignment
resource "vcd_vapp_vm" "DemoVM" {
vapp_name = vcd_vapp.Demo.name
name = var.vm_name
computer_name = var.vm_name
vapp_template_id = data.vcd_catalog_vapp_template.my-vapp-template.id
memory = 2048
cpus = 2
cpu_cores = 1
depends_on = [ vcd_vapp_org_network.vappOrgNet ]
network {
type = "org"
name = vcd_vapp_org_network.vappOrgNet.org_network_name
ip_allocation_mode = "MANUAL"
ip = var.vm_ip
is_primary = true
}
customization {
enabled = true
}
}
Můžeme také použít argument force, který způsobí restart VM při každé operaci terraform apply a vynucené přizpůsobení (force customization). Můžeme jej použít, pokud je potřeba rekonfigurace hosta, a poté opět vypnout.
Přímé zadání skriptu do atributu initscript
V bloku customization je argument initscript, do kterého můžeme přímo vložit obsah skriptu pro přizpůsobení. Máme tu jednoduchý příklad, který nastavuje hostname a síťové parametry (i když většinu těchto nastavení provádí Guest Customization automaticky) našeho VM s AlmaLinux 10.1.
customization {
enabled = true
initscript = <<-EOF
#!/bin/bash
hostnamectl hostname "${var.vm_name}"
nmcli connection modify ens192 ipv4.addresses "${var.vm_ip}/${var.vm_ip_mask}" ipv4.gateway ${var.vm_gw} ipv4.method manual ipv4.dns ${var.vm_dns} ipv6.method disable
nmcli device reapply ens192
EOF
}
Využití funkce templatefile pro načtení skriptu
Může být přehlednější uložit skript do samostatného souboru a využít funkci templatefile, která jej načte a nahradí zadané proměnné.
Vytvoříme soubor initscript.tftpl, do které vložíme obsah našeho skriptu.
#!/bin/bash
hostnamectl hostname "${vm_name}"
nmcli connection modify ens192 ipv4.addresses ${vm_ip_mask} ipv4.gateway ${vm_gw} ipv4.method manual ipv4.dns ${vm_dns} ipv6.method disable
nmcli device reapply ens192
Blok customization upravíme následně.
customization {
enabled = true
initscript = templatefile("initscript.tftpl", { vm_name = var.vm_name, vm_ip_mask = "${var.vm_ip}/${var.vm_ip_mask}", vm_gw = var.vm_gw, vm_dns = var.vm_dns })
}

Provedení části skriptu před nebo po přizpůsobení
Dokumentace VMware uvádí, že se skript volá s parametrem precustomization před přizpůsobením a parametrem postcustomization po přizpůsobení. Pomocí podmínek můžeme řídit, kdy se mají které příkazy provést.
Pozn.: V praxi se mi děje (patrně jen někdy), že se síťové připojení přejmenuje z ens192 na VMware customization ens192. Tak jsem do skriptu přidal příkaz, který přejmenuje zpět.
#!/bin/bash
if [ x$1 == x"precustomization" ]; then
echo "Do Precustomization tasks"
elif [ x$1 == x"postcustomization" ]; then
echo "Do Postcustomization tasks"
hostnamectl hostname "${vm_name}"
nmcli connection modify "VMware customization ens192" connection.id ens192
nmcli connection modify ens192 ipv4.addresses ${vm_ip_mask} ipv4.gateway ${vm_gw} ipv4.method manual ipv4.dns ${vm_dns} ipv6.method disable
nmcli device reapply ens192
fi
V některých případech může být potřeba nahradit v porovnání == za =. VCloud Guest Customization Script : [: postcustomization: unexpected operator
Aplikace změn konfigurace
Když máme konfiguraci připravenou, tak spustíme aktualizaci pomocí Terraform CLI příkazu terraform apply. Vytvoří se VM a nastaví přizpůsobení včetně našeho skriptu, který se spustí po startu VM.
Pouze část výstupu je uvedena níže.
PS D:\VCD-terraform> terraform apply
data.vcd_catalog.my-catalog: Reading...
...
Terraform will perform the following actions:
...
# vcd_vapp_vm.DemoVM will be created
+ resource "vcd_vapp_vm" "DemoVM" {
...
+ customization {
+ admin_password = (sensitive value)
+ allow_local_admin_password = (known after apply)
+ auto_generate_password = (known after apply)
+ change_sid = (known after apply)
+ enabled = true
+ initscript = <<-EOT
#!/bin/bash
if [ x$1 == x"precustomization" ]; then
echo "Do Precustomization tasks"
elif [ x$1 == x"postcustomization" ]; then
echo "Do Postcustomization tasks"
hostnamectl hostname "Demo-VM"
nmcli connection modify "VMware customization ens192" connection.id ens192
nmcli connection modify ens192 ipv4.addresses 172.30.21.100/22 ipv4.gateway 172.30.20.1 ipv4.method manual ipv4.dns 172.30.20.1 ipv6.method disable
nmcli device reapply ens192
fi
EOT
+ join_domain = (known after apply)
+ join_domain_account_ou = (known after apply)
+ join_domain_name = (known after apply)
+ join_domain_password = (sensitive value)
+ join_domain_user = (known after apply)
+ join_org_domain = (known after apply)
+ must_change_password_on_first_login = (known after apply)
+ number_of_auto_logons = (known after apply)
}
...
Vypnutí přizpůsobení na VM
Po prvním startu VM, kdy proběhlo přizpůsobení, se doporučuje Guest OS Customization vypnout. To znamená upravit konfiguraci bloku customization, kde nastavíme argument enabled = false. A znovu spustíme terraform apply.
customization {
enabled = false
initscript = templatefile("setup.tftpl", { vm_name = var.vm_name, vm_ip_mask = var.vm_ip_mask, vm_gw = var.vm_gw, vm_dns = var.vm_dns })
}
Pozn.: Snažil jsem se hledat, jak by se daly tyto dva kroky vyvolat najednou. Ale řešení jsem nenalezl. Podle diskusí je to běžný problém deklarativního přístupu.
Guest OS Customization logy
VMware Cloud Director uloží náš zadaný skript (na Linuxu) do souboru /root/.customization/customize.sh v hostovaném OS. Logy Guest OS Customization se ukládají do složky /var/log/vmware-imc/. Primární je soubor toolsDeployPkg.log, případně také customization.log.
Cloud-init
Narazil jsem na zmínky o dalších možnostech, jak přizpůsobit konfiguraci OS nových VM. Jeden zmiňovaný způsob je cloud-init. Prakticky jsem netestoval, ale popis je třeba v článku Using cloud-init for Customization with VCD and Terraform.
Zatím zde nejsou žádné komentáře.