180 lines
6.0 KiB
YAML
180 lines
6.0 KiB
YAML
---
|
|
# configure-vm.yml - Configure VM with UEFI, TPM, disks, GPU, and Cloud-Init
|
|
|
|
- name: "[CONFIG] Configure UEFI + Secure Boot + TPM (if enabled)"
|
|
block:
|
|
- name: "[CONFIG] Enable UEFI and TPM"
|
|
ansible.builtin.command: >
|
|
qm set {{ vm_id }}
|
|
--bios ovmf
|
|
--efidisk0 {{ storage }}:0,pre-enrolled-keys=1
|
|
--tpmstate0 {{ storage }}:1,size=4M,version=v2.0
|
|
register: tpm_config
|
|
changed_when: tpm_config.rc == 0
|
|
|
|
- name: "[CONFIG] Verify TPM configuration"
|
|
ansible.builtin.debug:
|
|
msg: "✓ UEFI + TPM configured for VM {{ vm_id }}"
|
|
|
|
when: enable_tpm | default(false)
|
|
|
|
- name: "[CONFIG] Import and attach disk"
|
|
block:
|
|
- name: "[CONFIG] Check if disk is already attached"
|
|
ansible.builtin.include_tasks: helpers.yml
|
|
vars:
|
|
helper_task: check_disk_attached
|
|
target_vm_id: "{{ vm_id }}"
|
|
|
|
- name: "[CONFIG] Display disk status"
|
|
ansible.builtin.debug:
|
|
msg: "Disk status for VM {{ vm_id }}: {{ 'ALREADY ATTACHED' if disk_attached else 'WILL BE IMPORTED & ATTACHED' }}"
|
|
|
|
- name: "[CONFIG] Import qcow2 disk (if not already attached)"
|
|
ansible.builtin.command: >
|
|
qm importdisk {{ vm_id }}
|
|
{{ debian_image_path }}
|
|
{{ storage }}
|
|
register: disk_import
|
|
retries: "{{ max_retries }}"
|
|
delay: "{{ retry_delay }}"
|
|
until: disk_import is succeeded
|
|
when: not disk_attached
|
|
|
|
- name: "[CONFIG] Verify disk import"
|
|
ansible.builtin.fail:
|
|
msg: "Disk import failed for VM {{ vm_id }}"
|
|
when:
|
|
- not disk_attached
|
|
- disk_import is failed
|
|
|
|
- name: "[CONFIG] Attach imported disk"
|
|
ansible.builtin.command: >
|
|
qm set {{ vm_id }}
|
|
--scsihw virtio-scsi-pci
|
|
--scsi0 {{ storage }}:vm-{{ vm_id }}-disk-0
|
|
register: disk_attach
|
|
when: not disk_attached
|
|
changed_when: disk_attach.rc == 0
|
|
|
|
- name: "[CONFIG] Enable serial console and set boot order"
|
|
ansible.builtin.command: >
|
|
qm set {{ vm_id }}
|
|
--serial0 socket
|
|
--boot order=scsi0
|
|
register: serial_config
|
|
changed_when: serial_config.rc == 0
|
|
|
|
- name: "[CONFIG] Display disk configuration"
|
|
ansible.builtin.debug:
|
|
msg: "✓ Disk {{ 'attached' if disk_attached else 'imported and attached' }} to VM {{ vm_id }}"
|
|
|
|
rescue:
|
|
- name: "[CONFIG] Handle disk configuration error"
|
|
ansible.builtin.fail:
|
|
msg: |
|
|
Failed to configure disk for VM {{ vm_id }}:
|
|
{{ ansible_failed_result | default('Unknown error') }}
|
|
|
|
- name: "[CONFIG] Resize disk (if enabled)"
|
|
block:
|
|
- name: "[CONFIG] Resize disk"
|
|
ansible.builtin.command: "qm resize {{ vm_id }} scsi0 {{ resize_size }}"
|
|
register: disk_resize
|
|
changed_when: disk_resize.rc == 0
|
|
|
|
- name: "[CONFIG] Display disk resize result"
|
|
ansible.builtin.debug:
|
|
msg: "✓ Disk resized to {{ resize_size }}"
|
|
|
|
when: resize_disk | default(false)
|
|
|
|
- name: "[CONFIG] Configure GPU passthrough (if enabled)"
|
|
block:
|
|
- name: "[CONFIG] Enable PCI GPU passthrough"
|
|
ansible.builtin.command: "qm set {{ vm_id }} --hostpci0 {{ gpu_device }}"
|
|
register: gpu_config
|
|
changed_when: gpu_config.rc == 0
|
|
|
|
- name: "[CONFIG] Display GPU configuration"
|
|
ansible.builtin.debug:
|
|
msg: "✓ GPU passthrough configured: {{ gpu_device }}"
|
|
|
|
when: gpu_passthrough | default(false)
|
|
|
|
- name: "[CONFIG] Configure VirtIO GPU (if enabled)"
|
|
block:
|
|
- name: "[CONFIG] Enable VirtIO GPU"
|
|
ansible.builtin.command: "qm set {{ vm_id }} --vga virtio"
|
|
register: virtio_gpu_config
|
|
changed_when: virtio_gpu_config.rc == 0
|
|
|
|
- name: "[CONFIG] Display VirtIO GPU configuration"
|
|
ansible.builtin.debug:
|
|
msg: "✓ VirtIO GPU configured"
|
|
|
|
when: virtio_gpu | default(false)
|
|
|
|
- name: "[CONFIG] Create and apply Cloud-Init snippets"
|
|
block:
|
|
- name: "[CONFIG] Clean up old Cloud-Init snippets (if any)"
|
|
ansible.builtin.include_tasks: helpers.yml
|
|
vars:
|
|
helper_task: cleanup_snippets
|
|
target_vm_id: "{{ vm_id }}"
|
|
|
|
- name: "[CONFIG] Create Cloud-Init vendor-data snippet"
|
|
ansible.builtin.template:
|
|
src: cloudinit_vendor.yaml.j2
|
|
dest: "{{ proxmox_snippets_storage_path }}/snippets/{{ vm_id }}-vendor.yaml"
|
|
mode: "0644"
|
|
register: vendor_snippet
|
|
|
|
- name: "[CONFIG] Verify SSH key is readable"
|
|
ansible.builtin.stat:
|
|
path: "{{ ssh_keys_file | expanduser }}"
|
|
register: ssh_key_stat
|
|
failed_when: not ssh_key_stat.stat.readable
|
|
|
|
- name: "[CONFIG] Create Cloud-Init user-data snippet"
|
|
ansible.builtin.template:
|
|
src: cloudinit_userdata.yaml.j2
|
|
dest: "{{ proxmox_snippets_storage_path }}/snippets/{{ vm_id }}-user.yaml"
|
|
mode: "0644"
|
|
register: user_snippet
|
|
|
|
- name: "[CONFIG] Copy SSH public key to snippets"
|
|
ansible.builtin.copy:
|
|
src: "{{ ssh_keys_file }}"
|
|
dest: "{{ proxmox_snippets_storage_path }}/snippets/{{ vm_id }}-sshkey.pub"
|
|
remote_src: true
|
|
mode: "0644"
|
|
register: ssh_snippet
|
|
|
|
- name: "[CONFIG] Apply Cloud-Init configuration"
|
|
ansible.builtin.command: >
|
|
qm set {{ vm_id }}
|
|
--ciuser {{ ci_user }}
|
|
--sshkeys "{{ proxmox_snippets_storage_path }}/snippets/{{ vm_id }}-sshkey.pub"
|
|
--citype nocloud
|
|
--cicustom "user=local:snippets/{{ vm_id }}-user.yaml,vendor=local:snippets/{{ vm_id }}-vendor.yaml"
|
|
--ipconfig0 {{ ipconfig0 }}
|
|
register: cloudinit_apply
|
|
changed_when: cloudinit_apply.rc == 0
|
|
|
|
- name: "[CONFIG] Display Cloud-Init configuration"
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
✓ Cloud-Init configured for VM {{ vm_id }}
|
|
- User: {{ ci_user }}
|
|
- Hostname: {{ hostname }}
|
|
- IP Config: {{ ipconfig0 }}
|
|
- Timezone: {{ timezone }}
|
|
|
|
rescue:
|
|
- name: "[CONFIG] Handle Cloud-Init configuration error"
|
|
ansible.builtin.fail:
|
|
msg: |
|
|
Failed to configure Cloud-Init for VM {{ vm_id }}:
|
|
{{ ansible_failed_result | default('Unknown error') }}
|