Virtualization TPM2 and cloud-init fixes
This commit is contained in:
11
roles/virtualization/defaults/main.yml
Normal file
11
roles/virtualization/defaults/main.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
virtualization_tpm2_enabled: >-
|
||||
{{
|
||||
(partitioning_luks_enabled | default(luks_enabled | default(false)) | bool)
|
||||
and (partitioning_luks_auto_decrypt | default(luks_auto_decrypt | default(true)) | bool)
|
||||
and (
|
||||
(partitioning_luks_auto_decrypt_method | default(luks_auto_decrypt_method | default('tpm2')))
|
||||
| lower
|
||||
== 'tpm2'
|
||||
)
|
||||
}}
|
||||
@@ -1,22 +1,34 @@
|
||||
---
|
||||
- name: Check if VM disk exists
|
||||
- name: Set libvirt image paths
|
||||
delegate_to: localhost
|
||||
ansible.builtin.stat:
|
||||
path: "{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2"
|
||||
register: vm_disk_stat
|
||||
vars:
|
||||
virtualization_libvirt_image_dir_value: "{{ vm_path | default('/var/lib/libvirt/images') }}"
|
||||
ansible.builtin.set_fact:
|
||||
virtualization_libvirt_image_dir: "{{ virtualization_libvirt_image_dir_value }}"
|
||||
virtualization_libvirt_disk_path: >-
|
||||
{{ [virtualization_libvirt_image_dir_value, hostname ~ '.qcow2'] | ansible.builtin.path_join }}
|
||||
virtualization_libvirt_cloudinit_path: >-
|
||||
{{ [virtualization_libvirt_image_dir_value, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
||||
changed_when: false
|
||||
|
||||
- name: Create VM disk
|
||||
when: not vm_disk_stat.stat.exists
|
||||
delegate_to: localhost
|
||||
ansible.builtin.command: qemu-img create -f qcow2 {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2 {{ vm_size }}G
|
||||
changed_when: result.rc == 0
|
||||
register: result
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- qemu-img
|
||||
- create
|
||||
- -f
|
||||
- qcow2
|
||||
- "{{ virtualization_libvirt_disk_path }}"
|
||||
- "{{ vm_size }}G"
|
||||
creates: "{{ virtualization_libvirt_disk_path }}"
|
||||
|
||||
- name: Generate Random MAC Address
|
||||
- name: Generate VM MAC address
|
||||
delegate_to: localhost
|
||||
ansible.builtin.shell: set -o pipefail && openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | sed 's/^/02:/'
|
||||
ansible.builtin.set_fact:
|
||||
virtualization_mac_address: >-
|
||||
{{ '52:54:00' | community.general.random_mac(seed=hostname) }}
|
||||
changed_when: false
|
||||
register: mac_address_output
|
||||
|
||||
- name: Render cloud config templates
|
||||
delegate_to: localhost
|
||||
@@ -25,17 +37,19 @@
|
||||
dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml
|
||||
mode: '0644'
|
||||
loop:
|
||||
- { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data }
|
||||
- { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config }
|
||||
- {src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data}
|
||||
- {src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config}
|
||||
|
||||
- name: Create cloud-init disk
|
||||
delegate_to: localhost
|
||||
ansible.builtin.command: >
|
||||
cloud-localds {{ vm_path | default('/var/lib/libvirt/images/') }}/{{ hostname }}-cloudinit.iso
|
||||
/tmp/cloud-user-data-{{ hostname }}.yml
|
||||
-N /tmp/cloud-network-config-{{ hostname }}.yml
|
||||
changed_when: result.rc == 0
|
||||
register: result
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cloud-localds
|
||||
- "{{ virtualization_libvirt_cloudinit_path }}"
|
||||
- "/tmp/cloud-user-data-{{ hostname }}.yml"
|
||||
- -N
|
||||
- "/tmp/cloud-network-config-{{ hostname }}.yml"
|
||||
creates: "{{ virtualization_libvirt_cloudinit_path }}"
|
||||
|
||||
- name: Create VM using libvirt
|
||||
delegate_to: localhost
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
---
|
||||
- name: Deploy VM on Proxmox
|
||||
delegate_to: localhost
|
||||
community.general.proxmox_kvm:
|
||||
vars:
|
||||
virtualization_dns_value: "{{ vm_dns | default('') }}"
|
||||
virtualization_dns_list_raw: >-
|
||||
{{
|
||||
virtualization_dns_value
|
||||
if virtualization_dns_value is iterable and virtualization_dns_value is not string
|
||||
else virtualization_dns_value.split(',')
|
||||
}}
|
||||
virtualization_dns_list: >-
|
||||
{{ virtualization_dns_list_raw | map('trim') | reject('equalto', '') | list }}
|
||||
virtualization_search_value: "{{ vm_dns_search | default('') }}"
|
||||
virtualization_search_list_raw: >-
|
||||
{{
|
||||
virtualization_search_value
|
||||
if virtualization_search_value is iterable and virtualization_search_value is not string
|
||||
else virtualization_search_value.split(',')
|
||||
}}
|
||||
virtualization_search_list: >-
|
||||
{{ virtualization_search_list_raw | map('trim') | reject('equalto', '') | list }}
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
@@ -17,7 +36,10 @@
|
||||
balloon: "{{ vm_ballo | default(omit) }}"
|
||||
numa_enabled: true
|
||||
hotplug: network,disk
|
||||
update: "{{ virtualization_tpm2_enabled | bool }}"
|
||||
update_unsafe: "{{ virtualization_tpm2_enabled | bool }}"
|
||||
bios: ovmf
|
||||
machine: "{{ 'q35' if virtualization_tpm2_enabled | bool else omit }}"
|
||||
boot: ac
|
||||
scsihw: virtio-scsi-single
|
||||
scsi:
|
||||
@@ -27,6 +49,12 @@
|
||||
format: raw
|
||||
pre_enrolled_keys: false
|
||||
storage: "{{ hypervisor_storage }}"
|
||||
tpmstate0: >-
|
||||
{{
|
||||
{'storage': hypervisor_storage, 'version': '2.0'}
|
||||
if virtualization_tpm2_enabled | bool
|
||||
else omit
|
||||
}}
|
||||
ide:
|
||||
ide0: "{{ boot_iso }},media=cdrom"
|
||||
ide1: "{{ rhel_iso + ',media=cdrom' if rhel_iso is defined else omit }}"
|
||||
@@ -34,14 +62,21 @@
|
||||
net:
|
||||
net0: virtio,bridge={{ vm_nif }}{% if vlan_name is defined and vlan_name %},tag={{ vlan_name }}{% endif %}
|
||||
ipconfig:
|
||||
ipconfig0: ip={{ vm_ip }}/{{ vm_nms | default(24) }},gw={{ vm_gw }}
|
||||
nameservers: "{{ vm_dns }}"
|
||||
ipconfig0: >-
|
||||
{{
|
||||
'ip=' ~ vm_ip ~ '/' ~ (vm_nms | default(24))
|
||||
~ (',gw=' ~ vm_gw if vm_gw is defined and vm_gw | length else '')
|
||||
if vm_ip is defined and vm_ip | length
|
||||
else 'ip=dhcp'
|
||||
}}
|
||||
nameservers: "{{ virtualization_dns_list if virtualization_dns_list | length else omit }}"
|
||||
searchdomains: "{{ virtualization_search_list if virtualization_search_list | length else omit }}"
|
||||
onboot: true
|
||||
state: present
|
||||
|
||||
- name: Start VM on Proxmox
|
||||
delegate_to: localhost
|
||||
community.general.proxmox_kvm:
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: Create VM in vCenter
|
||||
delegate_to: localhost
|
||||
community.vmware.vmware_guest:
|
||||
@@ -7,12 +8,12 @@
|
||||
validate_certs: false
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
cluster: "{{ hypervisor_cluster }}"
|
||||
folder: "{{ vm_path }}"
|
||||
folder: "{{ vm_path | default(omit) }}"
|
||||
name: "{{ hostname }}"
|
||||
guest_id: otherLinux64Guest
|
||||
annotation: |
|
||||
{{ note | default('') }}
|
||||
state: poweredon
|
||||
state: "{{ 'poweredoff' if virtualization_tpm2_enabled | bool else 'poweredon' }}"
|
||||
disk:
|
||||
- size_gb: "{{ vm_size }}"
|
||||
type: thin
|
||||
@@ -46,9 +47,28 @@
|
||||
- name: "{{ vm_nif }}"
|
||||
type: dhcp
|
||||
vlan: "{{ vlan_name | default(omit) }}"
|
||||
register: vmware_guest_result
|
||||
failed_when:
|
||||
- vmware_guest_result.failed is defined and vmware_guest_result.failed
|
||||
- "'error' in vmware_guest_result"
|
||||
- "'failed' in vmware_guest_result"
|
||||
- vmware_guest_result.rc is defined and vmware_guest_result.rc != 0
|
||||
|
||||
- name: Ensure vTPM2 is enabled when required
|
||||
when: virtualization_tpm2_enabled | bool
|
||||
delegate_to: localhost
|
||||
community.vmware.vmware_guest_tpm:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
folder: "{{ vm_path | default(omit) }}"
|
||||
name: "{{ hostname }}"
|
||||
state: present
|
||||
|
||||
- name: Start VM in vCenter
|
||||
when: virtualization_tpm2_enabled | bool
|
||||
delegate_to: localhost
|
||||
vmware.vmware.vm_powerstate:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
name: "{{ hostname }}"
|
||||
state: powered-on
|
||||
|
||||
@@ -3,9 +3,44 @@ network:
|
||||
ethernets:
|
||||
id0:
|
||||
match:
|
||||
macaddress: "{{ mac_address_output.stdout }}"
|
||||
macaddress: "{{ virtualization_mac_address }}"
|
||||
{% set has_static = vm_ip is defined and vm_ip | length %}
|
||||
{% set dns_value = vm_dns | default('') %}
|
||||
{% set dns_list_raw = dns_value if dns_value is iterable and dns_value is not string else dns_value.split(',') %}
|
||||
{% set dns_list = dns_list_raw | map('trim') | reject('equalto', '') | list %}
|
||||
{% set search_value = vm_dns_search | default('') %}
|
||||
{% set search_list_raw = search_value if search_value is iterable and search_value is not string else search_value.split(',') %}
|
||||
{% set search_list = search_list_raw | map('trim') | reject('equalto', '') | list %}
|
||||
{% if has_static %}
|
||||
addresses:
|
||||
- "{{ vm_ip }}"
|
||||
- "{{ vm_ip }}/{{ vm_nms | default(24) }}"
|
||||
{% if vm_gw is defined and vm_gw | length %}
|
||||
gateway4: "{{ vm_gw }}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
dhcp4: true
|
||||
{% if (vm_dns is defined and vm_dns | length) or (vm_dns_search is defined and vm_dns_search | length) %}
|
||||
dhcp4-overrides:
|
||||
{% if vm_dns is defined and vm_dns | length %}
|
||||
use-dns: false
|
||||
{% endif %}
|
||||
{% if vm_dns_search is defined and vm_dns_search | length %}
|
||||
use-domains: false
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if dns_list or search_list %}
|
||||
nameservers:
|
||||
addresses: ['1.1.1.1', '1.0.0.1']
|
||||
{% if dns_list %}
|
||||
addresses:
|
||||
{% for dns in dns_list %}
|
||||
- "{{ dns }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if search_list %}
|
||||
search:
|
||||
{% for search in search_list %}
|
||||
- "{{ search }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2'/>
|
||||
<source file='{{ virtualization_libvirt_disk_path }}'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type="file" device="cdrom">
|
||||
@@ -34,7 +34,7 @@
|
||||
</disk>
|
||||
<disk type="file" device="cdrom">
|
||||
<driver name="qemu" type="raw"/>
|
||||
<source file="{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}-cloudinit.iso"/>
|
||||
<source file="{{ virtualization_libvirt_cloudinit_path }}"/>
|
||||
<target dev="sdb" bus="sata"/>
|
||||
</disk>
|
||||
{% if rhel_iso is defined %}
|
||||
@@ -45,10 +45,15 @@
|
||||
</disk>
|
||||
{% endif %}
|
||||
<interface type='network'>
|
||||
<mac address="{{ mac_address_output.stdout }}"/>
|
||||
<mac address="{{ virtualization_mac_address }}"/>
|
||||
<source network='default'/>
|
||||
<model type='virtio'/>
|
||||
</interface>
|
||||
{% if virtualization_tpm2_enabled | default(false) %}
|
||||
<tpm model='tpm-crb'>
|
||||
<backend type='emulator' version='2.0'/>
|
||||
</tpm>
|
||||
{% endif %}
|
||||
<input type="tablet" bus="usb"/>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<input type="keyboard" bus="ps2"/>
|
||||
|
||||
Reference in New Issue
Block a user