vmware.vmware_rest.vcenter_vm_guest_customization module – Applies a customization specification on the virtual machine
Note
This module is part of the vmware.vmware_rest collection (version 4.2.0).
You might already have this collection installed if you are using the ansible
package.
It is not included in ansible-core
.
To check whether it is installed, run ansible-galaxy collection list
.
To install it, use: ansible-galaxy collection install vmware.vmware_rest
.
You need further requirements to be able to use this module,
see Requirements for details.
To use it in a playbook, specify: vmware.vmware_rest.vcenter_vm_guest_customization
.
New in vmware.vmware_rest 0.1.0
Synopsis
Applies a customization specification on the virtual machine in {@param.name vm}. The actual customization happens inside the guest when the virtual machine is powered on. If there is a pending customization for the virtual machine and a new one is set, then the existing customization setting will be overwritten with the new settings.
Requirements
The below requirements are needed on the host that executes this module.
vSphere 7.0.3 or greater
python >= 3.6
aiohttp
Parameters
Parameter |
Comments |
---|---|
Settings to be applied to the guest during the customization. This parameter is mandatory. Valid attributes are:
If unset, ConfigurationSpec.linux-config or ConfigurationSpec.cloud-config must be set. Otherwise, an appropriate fault will be thrown. ([‘set’])
Accepted value for this field:
If unset, sysprep settings will not be applied to the windows guest operating system.
If unset, sysprep settings will not be applied to the windows guest operating system.
If unset, ConfigurationSpec.windows-config or ConfigurationSpec.cloud-config must be set. Otherwise, an appropriate fault will be thrown. ([‘set’])
See the https://kb.vmware.com/kb/2145518 for a list of supported time zones for different versions in Linux. If unset, time zone is not modified inside guest operating system.
The max size of the script is 65536 bytes. As long as the script (shell, perl, python…) has the right “#!” in the header, it is supported. The caller should not assume any environment variables when the script is run. The script is invoked by the customization engine using the command line: 1) with argument “precustomization” before customization, 2) with argument “postcustomization” after customization. The script should parse this argument and implement pre-customization or post-customization task code details in the corresponding block. A Linux shell script example: #!/bin/sh if [ x$1 == x”precustomization” ]; then echo “Do Precustomization tasks” #code for pre-customization actions… elif [ x$1 == x”postcustomization” ]; then echo “Do Postcustomization tasks” #code for post-customization actions… fi If unset, no script will be executed.
If unset, ConfigurationSpec.windows-config or ConfigurationSpec.linux-config must be set. Otherwise, an appropriate fault will be thrown. ([‘set’])
Accepted value for this field:
This field is optional and it is only relevant when the value of CloudConfiguration.type is CLOUDINIT. |
|
Global DNS settings constitute the DNS settings that are not specific to a particular virtual network adapter. This parameter is mandatory. Valid attributes are:
If unset, no DNS suffixes are set. ([‘set’])
If unset, no DNS servers are set. ([‘set’]) |
|
IP settings that are specific to a particular virtual network adapter. The AdapterMapping structure maps a network adapter’s MAC address to its IPSettings. May be empty if there are no network adapters, else should match number of network adapters configured for the VM. This parameter is mandatory. Valid attributes are:
In vSphere 7.0 series, the MAC addresses must be specified in the ascending order of pciSlotNumber, otherwise a MAC address mismatch error will be reported. For further details, see the https://kb.vmware.com/s/article/87648 If unset, the customization process maps the the settings from the list of i_p_settings in the CustomizationSpec.interfaces to the virtual machine’s network adapters, in PCI slot order. The first virtual network adapter on the PCI bus is assigned interfaces[0].IPSettings, the second adapter is assigned interfaces[1].IPSettings, and so on. ([‘set’])
This key is required with [‘set’].
If unset, no IPv4 addresses are set.
If unset, no IPv6 addresses are set.
If unset, no specific Windows settings are set. |
|
Timeout settings for client session. The maximal number of seconds for the whole operation including connection establishment, request sending and response. The default value is 300s. |
|
Choices:
|
|
The hostname or IP address of the vSphere vCenter If the value is not specified in the task, the value of environment variable |
|
The vSphere vCenter password If the value is not specified in the task, the value of environment variable |
|
You can use this optional parameter to set the location of a log file. This file will be used to record the HTTP REST interaction. The file will be stored on the host that runs the module. If the value is not specified in the task, the value of environment variable |
|
The vSphere vCenter username If the value is not specified in the task, the value of environment variable |
|
Allows connection when SSL certificates are not valid. Set to If the value is not specified in the task, the value of environment variable Choices:
|
|
The unique identifier of the virtual machine that needs to be customized. The parameter must be the id of a resource returned by vmware.vmware_rest.vcenter_vm_info. This parameter is mandatory. |
Notes
Note
Tested on vSphere 7.0.3
Examples
##########
#
# VM customization can be difficult to troubleshoot, since each environment is different. Here are some general tips:
#
# 1. Make sure perl is installed on the Linux systems. Make sure cloud-init is installed if using cloud-init
# 2. Custom script execution is disabled by default. To enable it, you can run as root: vmware-toolbox-cmd config set deployPkg enable-custom-scripts true
# 3. VMware tools must be installed and recognized by vCenter before you can apply customization. See the example below for one approach to this.
# 4. On Linux (RHEL specifically), customization script logs can be found at /var/log/vmware-imc/toolsDeployPkg.log
# 5. Once the VM is started, the pending customization is applied. Even if that fails, the customization is then cleared. Meaning, you need to re-apply
# the customization spec in order to try again. Simply rebooting the VM will not change anything.
#
##########
# Here is the basic workflow for creating a new VM and then customizing it
- name: Deploy a new VM based on a template
vmware.vmware_rest.vcenter_vmtemplate_libraryitems:
name: vm-from-template
library: "{{ library_id }}"
template_library_item: "{{ template_id }}"
placement:
cluster: "{{ lookup('vmware.vmware_rest.cluster_moid', '/my_dc/host/my_cluster') }}"
state: deploy
register: my_new_vm
- name: Power on the VM to register VMware tools
vmware.vmware_rest.vcenter_vm_power:
state: start
vm: "{{ my_new_vm.id }}"
- name: Wait until my VMware tools are recognized
vmware.vmware_rest.vcenter_vm_tools_info:
vm: "{{ my_new_vm.id }}"
register: vm_tools_info
until:
- vm_tools_info is not failed
- vm_tools_info.value.run_state == "RUNNING"
retries: 60
delay: 5
- name: Power Off VM
vmware.vmware_rest.vcenter_vm_power:
state: stop
vm: "{{ my_new_vm.id }}"
- name: Customize the VM
vmware.vmware_rest.vcenter_vm_guest_customization:
vm: "{{ my_new_vm.id }}"
global_DNS_settings:
dns_suffix_list:
- lan
- foo.internal
dns_servers:
- "8.8.8.8"
interfaces:
- adapter:
ipv4:
type: DHCP
configuration_spec:
linux_config:
domain: test
hostname:
fixed_name: myhost
type: FIXED
# Here is an example using the Linux script text. The script shebang can be anything (bash, perl, python), so long as the script will actually run
# There is also size and length limitation on the script text, as described in the module documentation.
# Finally, note the script is run twice. Once before all of the other customization and once after.
- name: Customize the VM
vmware.vmware_rest.vcenter_vm_guest_customization:
vm: "{{ my_new_vm.id }}"
global_DNS_settings:
dns_suffix_list:
- lan
- foo.internal
dns_servers:
- "8.8.8.8"
interfaces:
- adapter:
ipv4:
type: DHCP
configuration_spec:
linux_config:
domain: test
hostname:
fixed_name: myhost
type: FIXED
script_text: |
#!/bin/sh
if [ x$1 == x"precustomization" ]; then
echo "PRE" >> /tmp/vmware_rest_init_script.log
# add any other pre-customization tasks here
fi
if [ x$1 == x"postcustomization" ]; then
echo "POST" >> /tmp/vmware_rest_init_script.log
# add any other post-customization tasks here
fi
# Here is a simple example using cloud-init
# See also:
# https://developer.broadcom.com/xapis/vsphere-automation-api/latest/vcenter/data-structures/Guest_CloudinitConfiguration/
# https://knowledge.broadcom.com/external/article/311895/how-to-customize-virtual-machine-using-c.html
# https://cloudinit.readthedocs.io/en/latest/reference/examples.html
# https://cloudinit.readthedocs.io/en/23.4.1/reference/datasources/vmware.html#walkthrough-of-guestinfo-keys-transport
#
# cloud-init required: metadata as plain-text JSON/YAML, maximum 512KB file size
# cloud-init optional: userdata as plain-text in raw cloud-init format with no compression / no base64 encoding, maximum 512KB file size
- name: Customize the VM
vmware.vmware_rest.vcenter_vm_guest_customization:
vm: "{{ my_new_vm.id }}"
global_DNS_settings:
dns_suffix_list: []
dns_servers:
- "8.8.8.8"
interfaces:
- adapter:
ipv4:
type: DHCP
configuration_spec:
cloud_config:
type: CLOUDINIT
cloudinit:
metadata: |
instance-id: cloud-vm-example-1
local-hostname: cloud-vm
network:
config: disabled
userdata: |
#cloud-config
disable_root: 0
write_files:
- content: |
This is a test
path: /root/cloud-init-example
# Here is a more complex cloud-init example
- name: Set cloud-init variables for customization specification
ansible.builtin.set_fact:
metadata_yaml:
instance-id: "{{ vm_name }}"
hostname: "{{ vm_name }}"
local-hostname: "{{ vm_name }}"
network:
version: 2
ethernets:
nics:
match:
name: e*
dhcp4: true
dhcp6: false
public_ssh_keys:
- "{{ lookup('ansible.builtin.file', vmware_vm_ssh_public_key_file_path) }}"
userdata_yaml_text: |
#cloud-config
hostname: {{ vm_name }}
fqdn: {{ vm_name }}.{{ vm_domain }}
disable_root: false
ssh_pwauth: false
ssh_deletekeys: true
ssh:
emit_keys_to_console: false
no_ssh_fingerprints: false
ssh_authorized_keys:
- {{ lookup('ansible.builtin.file', vmware_vm_ssh_public_key_file_path) }}
users:
- name: root
ssh_authorized_keys:
- {{ lookup('ansible.builtin.file', vmware_vm_ssh_public_key_file_path) }}
lock_passwd: false
write_files:
- path: /etc/cloud/cloud-init.disabled
permissions: "0644"
content: ""
- name: Apply customization specification to the VM in Powered Off state
vmware.vmware_rest.vcenter_vm_guest_customization:
vm: "{{ my_new_vm.id }}"
configuration_spec:
cloud_config:
type: CLOUDINIT
cloudinit:
metadata: "{{ metadata_yaml | to_json(ensure_ascii=true) }}"
userdata: "{{ userdata_yaml_text | trim }}" # remove last newline character
interfaces: []
global_DNS_settings: {}
Return Values
Common return values are documented here, the following are the fields unique to this module:
Key |
Description |
---|---|
Customize the VM Returned: On success Sample: |