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: customvalues).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
- 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 sched_.mem.pshare.salt_ was not set in my case):
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.
1
2
3
4
5
6
7
8
|
- 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:
1
2
|
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 wyred. If everything is fine (no VM with the same name) the vmware_guest_facts - task fails, but the error is ignored and the subsequent fail - task is skipped. If the vmware_guest_facts - task is successful (VM with the same name is found) the fail - task will stop the Playbook.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
- 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 library inside of my Ansible-Playground GitHub Repository.