refactor ♻️: Refactored the Debian VM template and cloning tasks for improved readability and maintainability.
Improved the structure and organization of the tasks to make it easier to understand and modify. Added comments and whitespace to enhance readability.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
---
|
||||
vm_id: 150
|
||||
hostname: debian-template-base
|
||||
|
||||
@@ -6,48 +7,73 @@ cores: 4
|
||||
bridge: vmbr0
|
||||
storage: local-lvm
|
||||
cpu_type: host
|
||||
mac_address: "DE:AD:BE:EF:44:55"
|
||||
|
||||
# Networking for template VM
|
||||
ip_mode: dhcp
|
||||
ipconfig0: "ip=dhcp"
|
||||
# Default MAC generator: avoids collisions
|
||||
mac_base: "DE:AD:BE"
|
||||
mac_suffix: "{{ '%02X:%02X' | format((vm_id // 256) % 256, vm_id % 256) }}"
|
||||
mac_address: "{{ mac_base }}:{{ mac_suffix }}"
|
||||
|
||||
###############
|
||||
# Networking
|
||||
###############
|
||||
ip_mode: dhcp # or static
|
||||
ip_address: "192.168.1.60/24"
|
||||
gateway: "192.168.1.1"
|
||||
dns:
|
||||
- "1.1.1.1"
|
||||
- "8.8.8.8"
|
||||
|
||||
ipconfig0: "{{ 'ip=dhcp' if ip_mode == 'dhcp' else 'ip=' + ip_address + ',gw=' + gateway }}"
|
||||
|
||||
###############
|
||||
# Packages
|
||||
###############
|
||||
packages:
|
||||
- qemu-guest-agent
|
||||
- curl
|
||||
- htop
|
||||
|
||||
###############
|
||||
# Cloud-Init user + SSH + password
|
||||
###############
|
||||
ci_user: debian
|
||||
ci_password: "SecurePass123"
|
||||
ci_password: "SecurePass123" # consider vault
|
||||
ssh_key_path: "~/.ssh/id_rsa.pub"
|
||||
timezone: "Europe/Berlin"
|
||||
|
||||
###############
|
||||
# Optional Disk Resize
|
||||
###############
|
||||
resize_disk: true
|
||||
resize_size: "16G"
|
||||
|
||||
###############
|
||||
# GPU Options
|
||||
###############
|
||||
gpu_passthrough: false
|
||||
gpu_device: "0000:01:00.0"
|
||||
virtio_gpu: false
|
||||
|
||||
###############
|
||||
# TPM + Secure Boot
|
||||
###############
|
||||
enable_tpm: false
|
||||
|
||||
##########################
|
||||
# NEW OPTIONS
|
||||
##########################
|
||||
|
||||
# Convert VM to template?
|
||||
make_template: true
|
||||
|
||||
# Create clones from the template?
|
||||
create_clones: true
|
||||
|
||||
# List of clones to generate
|
||||
# List of clones
|
||||
clones:
|
||||
- id: 301
|
||||
hostname: app01
|
||||
ip: "192.168.1.81/24"
|
||||
gateway: "192.168.1.1"
|
||||
|
||||
full: 1
|
||||
- id: 302
|
||||
hostname: app02
|
||||
ip: "192.168.1.82/24"
|
||||
gateway: "192.168.1.1"
|
||||
full: 0
|
||||
|
||||
101
tasks/main.yml
101
tasks/main.yml
@@ -1,7 +1,8 @@
|
||||
---
|
||||
- name: Create a Debian VM template and optionally deploy clones
|
||||
- name: "Create a Debian VM template and optionally deploy clones"
|
||||
hosts: localhost
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
|
||||
@@ -9,132 +10,158 @@
|
||||
# 1. Ensure Debian GenericCloud Image Exists
|
||||
##################################################################
|
||||
- name: Check for Debian image
|
||||
ansible.builtin.stat:
|
||||
stat:
|
||||
path: "/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2"
|
||||
register: debian_img
|
||||
|
||||
- name: Download GenericCloud qcow2
|
||||
ansible.builtin.get_url:
|
||||
get_url:
|
||||
url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
|
||||
dest: "/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2"
|
||||
mode: "0644"
|
||||
when: not debian_img.stat.exists
|
||||
|
||||
##################################################################
|
||||
# 2. Create Base VM
|
||||
# 2. Create Base VM (if not exists)
|
||||
##################################################################
|
||||
- name: Check if VM exists
|
||||
stat:
|
||||
path: "/etc/pve/qemu-server/{{ vm_id }}.conf"
|
||||
register: vm_conf
|
||||
|
||||
- name: Create VM
|
||||
ansible.builtin.command: >
|
||||
command: >
|
||||
qm create {{ vm_id }}
|
||||
--name {{ hostname }}
|
||||
--memory {{ memory }}
|
||||
--cores {{ cores }}
|
||||
--cpu {{ cpu_type }}
|
||||
--net0 virtio,bridge={{ bridge }},macaddr={{ mac_address }}
|
||||
args:
|
||||
creates: "/etc/pve/qemu-server/{{ vm_id }}.conf"
|
||||
--agent 1
|
||||
when: not vm_conf.stat.exists
|
||||
|
||||
##################################################################
|
||||
# 3. Optional UEFI + Secure Boot + TPM 2.0
|
||||
# 3. Optional UEFI + Secure Boot + TPM
|
||||
##################################################################
|
||||
- name: Enable UEFI + Secure Boot + TPM (optional)
|
||||
ansible.builtin.command: >
|
||||
- name: Enable UEFI + TPM
|
||||
command: >
|
||||
qm set {{ vm_id }}
|
||||
--bios ovmf
|
||||
--efidisk0 {{ storage }}:1,pre-enrolled-keys=1
|
||||
--efidisk0 {{ storage }}:0,pre-enrolled-keys=1
|
||||
--tpmstate0 {{ storage }}:1,size=4M,version=v2.0
|
||||
when: enable_tpm | default(false)
|
||||
|
||||
##################################################################
|
||||
# 4. Disk Import
|
||||
# 4. Disk Import & Attach
|
||||
##################################################################
|
||||
- name: Check if disk already exists
|
||||
stat:
|
||||
path: "/var/lib/vz/images/{{ vm_id }}/vm-{{ vm_id }}-disk-0.qcow2"
|
||||
register: disk_exists
|
||||
|
||||
- name: Import qcow2 disk
|
||||
ansible.builtin.command: >
|
||||
command: >
|
||||
qm importdisk {{ vm_id }}
|
||||
/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2
|
||||
{{ storage }}
|
||||
when: not disk_exists.stat.exists
|
||||
|
||||
- name: Attach imported disk
|
||||
ansible.builtin.command: >
|
||||
command: >
|
||||
qm set {{ vm_id }}
|
||||
--scsihw virtio-scsi-pci
|
||||
--scsi0 {{ storage }}:vm-{{ vm_id }}-disk-0
|
||||
when: not disk_exists.stat.exists
|
||||
|
||||
- name: Enable serial console + boot disk
|
||||
command: >
|
||||
qm set {{ vm_id }}
|
||||
--serial0 socket
|
||||
--boot order=scsi0
|
||||
|
||||
##################################################################
|
||||
# 5. Optional Disk Resize
|
||||
##################################################################
|
||||
- name: Resize disk
|
||||
ansible.builtin.command: >
|
||||
qm resize {{ vm_id }} scsi0 {{ resize_size }}
|
||||
command: qm resize {{ vm_id }} scsi0 {{ resize_size }}
|
||||
when: resize_disk | default(false)
|
||||
|
||||
##################################################################
|
||||
# 6. Optional GPU Passthrough
|
||||
# 6. Optional GPU
|
||||
##################################################################
|
||||
- name: PCI GPU passthrough
|
||||
ansible.builtin.command: >
|
||||
qm set {{ vm_id }} --hostpci0 {{ gpu_device }}
|
||||
command: qm set {{ vm_id }} --hostpci0 {{ gpu_device }}
|
||||
when: gpu_passthrough | default(false)
|
||||
|
||||
- name: VirtIO GPU passthrough
|
||||
ansible.builtin.command: >
|
||||
qm set {{ vm_id }} --vga virtio
|
||||
- name: VirtIO GPU
|
||||
command: qm set {{ vm_id }} --vga virtio
|
||||
when: virtio_gpu | default(false)
|
||||
|
||||
##################################################################
|
||||
# 7. Cloud-Init Templates
|
||||
# 7. Cloud-Init Snippets
|
||||
##################################################################
|
||||
- name: Create Cloud-Init vendor-data
|
||||
ansible.builtin.template:
|
||||
template:
|
||||
src: cloudinit_vendor.yaml.j2
|
||||
dest: "/var/lib/vz/snippets/{{ vm_id }}-vendor.yaml"
|
||||
|
||||
- name: Create Cloud-Init user-data
|
||||
ansible.builtin.template:
|
||||
template:
|
||||
src: cloudinit_userdata.yaml.j2
|
||||
dest: "/var/lib/vz/snippets/{{ vm_id }}-user.yaml"
|
||||
|
||||
- name: Write SSH key snippet
|
||||
copy:
|
||||
content: "{{ lookup('file', ssh_key_path) }}"
|
||||
dest: "/var/lib/vz/snippets/{{ vm_id }}-sshkey.pub"
|
||||
|
||||
##################################################################
|
||||
# 8. Apply Cloud-Init
|
||||
##################################################################
|
||||
- name: Apply Cloud-Init config
|
||||
ansible.builtin.command: >
|
||||
command: >
|
||||
qm set {{ vm_id }}
|
||||
--ciuser {{ ci_user }}
|
||||
--cipassword '{{ ci_password }}'
|
||||
--sshkeys "{{ lookup('file', ssh_key_path) }}"
|
||||
--sshkeys local:snippets/{{ vm_id }}-sshkey.pub
|
||||
--hostname {{ hostname }}
|
||||
--citype nocloud
|
||||
--cicustom "user=local:snippets/{{ vm_id }}-user.yaml,vendor=local:snippets/{{ vm_id }}-vendor.yaml"
|
||||
--ipconfig0 {{ ipconfig0 }}
|
||||
|
||||
##################################################################
|
||||
# 9. Optional Convert Base VM to Template
|
||||
# 9. Convert VM to Template
|
||||
##################################################################
|
||||
- name: Convert VM to template
|
||||
ansible.builtin.command: qm template {{ vm_id }}
|
||||
command: qm template {{ vm_id }}
|
||||
when: make_template | default(false)
|
||||
args:
|
||||
creates: "/etc/pve/qemu-server/{{ vm_id }}.conf.lock"
|
||||
|
||||
##################################################################
|
||||
# 10. Optionally Create Cloud-Init Clones from Template
|
||||
# 10. Create Clones (if enabled)
|
||||
##################################################################
|
||||
- name: Create clones from template (optional)
|
||||
- name: Create clones from template
|
||||
when: create_clones | default(false)
|
||||
loop: "{{ clones }}"
|
||||
loop_control:
|
||||
loop_var: clone
|
||||
|
||||
block:
|
||||
- name: Check if clone exists
|
||||
stat:
|
||||
path: "/etc/pve/qemu-server/{{ clone.id }}.conf"
|
||||
register: clone_conf
|
||||
|
||||
- name: Clone VM from template
|
||||
ansible.builtin.command: >
|
||||
qm clone {{ vm_id }} {{ clone.id }} --name {{ clone.hostname }}
|
||||
command: >
|
||||
qm clone {{ vm_id }} {{ clone.id }} --name {{ clone.hostname }} --full {{ clone.full }}
|
||||
when: not clone_conf.stat.exists
|
||||
|
||||
- name: Apply cloud-init settings for clone
|
||||
ansible.builtin.command: >
|
||||
- name: Apply Cloud-Init settings for clone
|
||||
command: >
|
||||
qm set {{ clone.id }}
|
||||
--hostname {{ clone.hostname }}
|
||||
--ipconfig0 ip={{ clone.ip }},gw={{ clone.gateway }}
|
||||
|
||||
- name: Start clone VM
|
||||
ansible.builtin.command: qm start {{ clone.id }}
|
||||
command: qm start {{ clone.id }}
|
||||
|
||||
Reference in New Issue
Block a user