Since security is a requirement for the complete infrastructure stack, we will cover the vSphere VM Security Configuration with Ansible in this article. One of my prior posts has already covered the VMware ESXi Security Configuration with Ansible and is a good starting point when you are new to this topic.
VM Security Configuration
The vSphere 6.7 Update 1 Security Configuration Guidehas different subject areas regarding VM Security Configuration: Configure only the minimum required devices, disable unexposed features, limit the information you collect and disable non-essential features. I have additionally added the use of UEFI Secure Boot, if possible.
vSphere VM Advanced Options with Ansible
Most of the recommendations require an additional Advanced Option. The Ansible Module vmware_guest, which is needed anyway to create the vSphere VM, is able to set Advanced Options (Parameter:
- name: Create new VM - {{ vm_name }} vmware_guest: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: "{{ vm_datacenter }}" cluster: "{{ vm_cluster }}" validate_certs: no folder: "{{ vm_folder }}" name: "{{ vm_name }}" state: poweredoff guest_id: rhel7_64Guest datastore: "{{ vm_datastore }}" disk: - size_gb: 10 hardware: memory_mb: "{{ vm_mem }}" memory_reservation: "{{ (vm_mem / 2) | int }}" num_cpus: "{{ vm_cpu }}" cpu_reservation: "{{ (vm_cpu * 256) | int }}" scsi: paravirtual boot_firmware: efi networks: - name: "{{ vm_network }}" device_type: vmxnet3 customvalues: - key: "isolation.tools.copy.disable" value: "True" - key: "isolation.tools.paste.disable" value: "True" - key: "isolation.tools.diskShrink.disable" value: "True" - key: "isolation.tools.diskWiper.disable" value: "True" - key: "mks.enable3d" value: "False" - key: "tools.setInfo.sizeLimit" value: "1048576" - key: "RemoteDisplay.vnc.enabled" value: "False" - key: "tools.guestlib.enableHostInfo" value: "False" wait_for_ip_address: no register: vm_deploy
I have chosen these options from the vSphere 6.7 Update 1 Security Configuration Guide (svga.vgaOnly and
Description | Option |
Explicitly disable copy/paste operations | isolation.tools.copy.disable |
Explicitly disable copy/paste operations | isolation.tools.paste.disable |
Disable virtual disk shrinking | isolation.tools.diskShrink.disable |
Disable virtual disk shrinking | isolation.tools.diskWiper.disable |
Disable 3D features on Server and desktop virtual machines | mks.enable3d |
Limit informational messages from the VM to the VMX file | tools.setInfo.sizeLimit |
Control access to VM console via VNC protocol | RemoteDisplay.vnc.enabled |
Do not send host information to guests | tools.guestlib.enableHostInfo |
Another great Advanced Option that can be set during the provisioning is “ctkEnabled = TRUE”. If you enable Changed Block Tracking (CBT) prior first boot of the VM you prevent the annoying situation that your backup software (e.g. Veeam Backup & Replication) is not able to activate CBT during the backup job because of an existing VM Snapshot.
UEFI Secure Boot with Ansible
If you want to activate UEFI Secure Boot within the vSphere VM Security Configuration with Ansible you need the vmware_guest_boot_manager Preview Module from the Ansible 2.8 Dev Branch.
- name: Enable UEFI SecureBoot for {{ vm_name }} vmware_guest_boot_manager: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" validate_certs: no uuid: '{{ vm_deploy.instance.hw_product_uuid }}' secure_boot_enabled: True
Be aware that only newer guest operation systems support UEFI Secure Boot. I have verified Windows 2016, RHEL 7 and CentOS 7 running on VMware ESXi 6.7 Update 1.
Ansible Playbook
My complete Playbook for the vSphere VM Security Configuration with Ansible covers two additional extras:
- Check for existing VM with the same name
- CPU and Memory Reservation
The CPU and Memory Reservation done with the vmware_guest module was recently fixed with the PR #56161 by Abhijeet. With older versions of the module, the CPU and Memory Reservation had to be set in dedicated tasks.
My Playbook sets 50% of the memory and 256Mhz per vCPU as reservation:
memory_reservation: "{{ (vm_mem / 2) | int }}" cpu_reservation: "{{ (vm_cpu * 256) | int }}"
The task for the verification for a possible existing VM with the same name acts a little bit

- name: Create a VM with security configuration hosts: localhost gather_facts: no vars: vm_datacenter: lab vm_cluster: cluster01 vm_folder: /{{ vm_datacenter }}/vm/ vm_name: test_vm_01 vm_cpu: 1 vm_mem: 256 vm_datastore: datastore1 vm_network: DPortGroup1 tasks: - name: Check for existing VM with the same name vmware_guest_facts: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: "{{ vm_datacenter }}" validate_certs: no name: "{{ vm_name }}" ignore_errors: True register: vm_find - fail: msg: "The VM already exists." when: vm_find is succeeded - name: Create new VM - {{ vm_name }} vmware_guest: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: "{{ vm_datacenter }}" cluster: "{{ vm_cluster }}" validate_certs: no folder: "{{ vm_folder }}" name: "{{ vm_name }}" state: poweredoff guest_id: rhel7_64Guest datastore: "{{ vm_datastore }}" disk: - size_gb: 10 hardware: memory_mb: "{{ vm_mem }}" memory_reservation: "{{ (vm_mem / 2) | int }}" num_cpus: "{{ vm_cpu }}" cpu_reservation: "{{ (vm_cpu * 256) | int }}" scsi: paravirtual boot_firmware: efi networks: - name: "{{ vm_network }}" device_type: vmxnet3 customvalues: - key: "isolation.tools.copy.disable" value: "True" - key: "isolation.tools.paste.disable" value: "True" - key: "isolation.tools.diskShrink.disable" value: "True" - key: "isolation.tools.diskWiper.disable" value: "True" - key: "mks.enable3d" value: "False" - key: "tools.setInfo.sizeLimit" value: "1048576" - key: "RemoteDisplay.vnc.enabled" value: "False" - key: "tools.guestlib.enableHostInfo" value: "False" wait_for_ip_address: no register: vm_deploy - name: Enable UEFI SecureBoot for {{ vm_name }} vmware_guest_boot_manager: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" validate_certs: no uuid: '{{ vm_deploy.instance.hw_product_uuid }}' secure_boot_enabled: True
This Playbook can be found together with other vSphere related Playbooks and the required module l
Just for the record: 2.8 isn’t the dev branch anymore. 2.8.0 has been released a couple of days ago.
That’s awsome news. Thanks for the update
Very good posts Markus, but what would be the use case for ESXi hosts management when you have host profiles? Managing other aspects of a vSphere environment would make sense. But otherwise…… maybe if you have a requirement to use only a single tool for managing hosts. Or having a tool that spans multiple instances of vCenter perhaps.
Thanks for you feedback.
You are right with host profiles, this playbook is not required (first host needs also to be configured).
Keep in mind that not all environment can benefit from Host profiles. Mostly because of license feature level.
There might also be the required to document the enforcement of these settings. In this case a executed playbook also pretty nice