From 099fce9672f897557abf720dadd029fcf92f3c59 Mon Sep 17 00:00:00 2001 From: Jose Date: Sat, 8 Nov 2025 08:46:23 +0100 Subject: [PATCH] =?UTF-8?q?feat=20=E2=9C=A8:=20Added=20new=20Debian=20Clou?= =?UTF-8?q?d=20Template=20directly=20from=20Proxmox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created a new playbook to build and customize a Debian cloud image inside an LXC container, which is then imported as a Proxmox VM template. --- tasks/create_proxmox_debian_template.yml | 159 +++++++++++++++++++++ tasks/create_proxmox_debian_template1.yml | 162 ++++++++++++++++++++++ vars/debian_template.yml | 8 ++ 3 files changed, 329 insertions(+) create mode 100644 tasks/create_proxmox_debian_template.yml create mode 100644 tasks/create_proxmox_debian_template1.yml create mode 100644 vars/debian_template.yml diff --git a/tasks/create_proxmox_debian_template.yml b/tasks/create_proxmox_debian_template.yml new file mode 100644 index 0000000..531b328 --- /dev/null +++ b/tasks/create_proxmox_debian_template.yml @@ -0,0 +1,159 @@ +--- +- name: Build Debian Cloud Template directly from Proxmox + hosts: node0 + become: true + gather_facts: false + + vars_files: + - ../vars/debian_template.yml + + vars: + lxc_name: "debian-builder" + lxc_id: 9900 + lxc_storage: "local-lvm" + lxc_template: "local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst" + lxc_ostype: "debian" + lxc_cores: 2 + lxc_memory: 2048 + lxc_net: "name=eth0,bridge=vmbr0,ip=dhcp" + lxc_rootfs_size: "8G" + + tasks: + - block: + + - name: Ensure build environment packages are installed on Proxmox + ansible.builtin.apt: + name: + # - libguestfs-tools + # - qemu-utils + - rsync + state: present + update_cache: true + + - name: Create LXC build container + ansible.builtin.command: > + pct create {{ lxc_id }} {{ lxc_template }} + --hostname {{ lxc_name }} + --cores {{ lxc_cores }} + --memory {{ lxc_memory }} + --ostype {{ lxc_ostype }} + --net0 {{ lxc_net }} + --rootfs {{ lxc_storage }}:{{ lxc_rootfs_size }} + --features nesting=1 + --start + args: + creates: "/etc/pve/lxc/{{ lxc_id }}.conf" + + - name: Wait for LXC to boot and get IP + ansible.builtin.shell: "pct exec {{ lxc_id }} -- hostname -I | awk '{print $1}'" + register: lxc_ip + until: lxc_ip.stdout | ipaddr + retries: 20 + delay: 3 + + - name: Add temporary LXC to in-memory inventory + ansible.builtin.add_host: + name: lxc_builder + ansible_host: "{{ lxc_ip.stdout }}" + ansible_user: root + ansible_ssh_common_args: '-o StrictHostKeyChecking=no' + when: lxc_create is changed or lxc_create is succeeded + +- name: Customize Debian cloud image inside LXC + hosts: lxc_builder + become: true + + vars_files: + - ../vars/debian_template.yml + + tasks: + - block: + + - name: Install build dependencies in LXC + ansible.builtin.apt: + name: + - qemu-utils + - libguestfs-tools + - curl + - wget + - rsync + - xz-utils + - nano + - htop + state: present + update_cache: true + + - name: Create working directory + ansible.builtin.file: + path: "{{ workdir }}" + state: directory + + - name: Download latest Debian genericcloud image + ansible.builtin.get_url: + url: "{{ debian_image_url }}" + dest: "{{ workdir }}/{{ image_name }}" + mode: "0644" + force: true + + - name: Customize image with base utilities and root password + ansible.builtin.command: > + virt-customize -a {{ workdir }}/{{ image_name }} + --install "curl,wget,nano,rsync,htop" + --root-password password:{{ root_password }} + + - name: Set DHCP identifier to hostname for cloud-init + ansible.builtin.shell: | + virt-customize -a {{ workdir }}/{{ image_name }} \ + --run-command "echo 'dhcp-identifier: hostname' >> /etc/cloud/cloud.cfg.d/99_hostname.cfg" + + - name: Reset machine-id + ansible.builtin.shell: | + virt-customize -a {{ workdir }}/{{ image_name }} \ + --run-command 'truncate -s 0 /etc/machine-id && rm -f /var/lib/dbus/machine-id' + + - name: Compress and shrink image + ansible.builtin.shell: | + qemu-img convert -O qcow2 -c {{ workdir }}/{{ image_name }} {{ workdir }}/{{ template_name }}.qcow2 + qemu-img resize {{ workdir }}/{{ template_name }}.qcow2 --shrink + + - name: Copy finished template back to Proxmox host + ansible.builtin.synchronize: + src: "{{ workdir }}/{{ template_name }}.qcow2" + dest: "/var/lib/vz/template/qcow2/" + mode: pull + rsync_opts: + - "--rsync-path='sudo rsync'" + +- name: Import Debian Cloud image as Proxmox VM template + hosts: node0 + become: true + + tasks: + - block: + - name: Import QCOW2 as disk to new VM + ansible.builtin.shell: > + qm create {{ proxmox_template_vm_id }} + --name {{ template_name }} + --memory 1024 + --net0 virtio,bridge=vmbr0 && + qm importdisk {{ proxmox_template_vm_id }} + /var/lib/vz/template/qcow2/{{ template_name }}.qcow2 {{ proxmox_storage }} + + - name: Configure VM for Cloud-Init + ansible.builtin.shell: | + qm set {{ proxmox_template_vm_id }} \ + --scsihw virtio-scsi-pci \ + --scsi0 {{ proxmox_storage }}:vm-{{ proxmox_template_vm_id }}-disk-0 \ + --ide2 {{ proxmox_storage }}:cloudinit \ + --boot c --bootdisk scsi0 \ + --serial0 socket --vga serial0 + + - name: Convert VM to template + ansible.builtin.shell: "qm template {{ proxmox_template_vm_id }}" + + - name: Stop and destroy LXC build container + ansible.builtin.shell: "pct stop {{ lxc_id }} && pct destroy {{ lxc_id }} --purge" + ignore_errors: true + + - ansible.builtin.debug: + msg: "✅ Debian Cloud-Init template {{ template_name }} (VMID {{ proxmox_template_vm_id }}) created successfully!" diff --git a/tasks/create_proxmox_debian_template1.yml b/tasks/create_proxmox_debian_template1.yml new file mode 100644 index 0000000..11ee5a5 --- /dev/null +++ b/tasks/create_proxmox_debian_template1.yml @@ -0,0 +1,162 @@ +--- +- name: Build Debian Cloud Template directly from Proxmox + hosts: node0 + become: true + gather_facts: false + + vars_files: + - ../vars/debian_template.yml + + vars: + lxc_name: "debian-builder" + lxc_id: 9900 + lxc_storage: "local-lvm" + lxc_template: "local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst" + lxc_ostype: "debian" + lxc_cores: 2 + lxc_memory: 2048 + lxc_net: "name=eth0,bridge=vmbr0,ip=dhcp" + lxc_rootfs_size: "8G" + + tasks: + - block: + + - name: Ensure build environment packages are installed on Proxmox + ansible.builtin.apt: + name: + # - libguestfs-tools + # - qemu-utils + - rsync + state: present + update_cache: true + + - name: Create LXC build container + community.proxmox.lxc: + node: "{{ inventory_hostname }}" + vmid: "{{ lxc_id }}" + template: "{{ lxc_template }}" + hostname: "{{ lxc_name }}" + cores: "{{ lxc_cores }}" + memory: "{{ lxc_memory }}" + ostype: "{{ lxc_ostype }}" + net: "{{ lxc_net }}" + rootfs: "{{ lxc_storage }}:{{ lxc_rootfs_size }}" + features: + nesting: 1 + state: started + register: lxc_create + ignore_errors: true + + - name: Wait for LXC to boot and get IP + ansible.builtin.shell: "pct exec {{ lxc_id }} -- hostname -I | awk '{print $1}'" + register: lxc_ip + until: lxc_ip.stdout | ipaddr + retries: 20 + delay: 3 + + - name: Add temporary LXC to in-memory inventory + ansible.builtin.add_host: + name: lxc_builder + ansible_host: "{{ lxc_ip.stdout }}" + ansible_user: root + ansible_ssh_common_args: '-o StrictHostKeyChecking=no' + when: lxc_create is changed or lxc_create is succeeded + +- name: Customize Debian cloud image inside LXC + hosts: lxc_builder + become: true + + vars_files: + - ../vars/debian_template.yml + + tasks: + - block: + + - name: Install build dependencies in LXC + ansible.builtin.apt: + name: + - qemu-utils + - libguestfs-tools + - curl + - wget + - rsync + - xz-utils + - nano + - htop + state: present + update_cache: true + + - name: Create working directory + ansible.builtin.file: + path: "{{ workdir }}" + state: directory + + - name: Download latest Debian genericcloud image + ansible.builtin.get_url: + url: "{{ debian_image_url }}" + dest: "{{ workdir }}/{{ image_name }}" + mode: "0644" + force: true + + - name: Customize image with base utilities and root password + ansible.builtin.command: > + virt-customize -a {{ workdir }}/{{ image_name }} + --install "curl,wget,nano,rsync,htop" + --root-password password:{{ root_password }} + + - name: Set DHCP identifier to hostname for cloud-init + ansible.builtin.shell: | + virt-customize -a {{ workdir }}/{{ image_name }} \ + --run-command "echo 'dhcp-identifier: hostname' >> /etc/cloud/cloud.cfg.d/99_hostname.cfg" + + - name: Reset machine-id + ansible.builtin.shell: | + virt-customize -a {{ workdir }}/{{ image_name }} \ + --run-command 'truncate -s 0 /etc/machine-id && rm -f /var/lib/dbus/machine-id' + + - name: Compress and shrink image + ansible.builtin.shell: | + qemu-img convert -O qcow2 -c {{ workdir }}/{{ image_name }} {{ workdir }}/{{ template_name }}.qcow2 + qemu-img resize {{ workdir }}/{{ template_name }}.qcow2 --shrink + + - name: Copy finished template back to Proxmox host + ansible.builtin.synchronize: + src: "{{ workdir }}/{{ template_name }}.qcow2" + dest: "/var/lib/vz/template/qcow2/" + mode: pull + rsync_opts: + - "--rsync-path='sudo rsync'" + +- name: Import Debian Cloud image as Proxmox VM template + hosts: node0 + become: true + + tasks: + - block: + - name: Import QCOW2 as disk to new VM + ansible.builtin.shell: > + qm create {{ proxmox_template_vm_id }} + --name {{ template_name }} + --memory 1024 + --net0 virtio,bridge=vmbr0 && + qm importdisk {{ proxmox_template_vm_id }} + /var/lib/vz/template/qcow2/{{ template_name }}.qcow2 {{ proxmox_storage }} + + - name: Configure VM for Cloud-Init + ansible.builtin.shell: | + qm set {{ proxmox_template_vm_id }} \ + --scsihw virtio-scsi-pci \ + --scsi0 {{ proxmox_storage }}:vm-{{ proxmox_template_vm_id }}-disk-0 \ + --ide2 {{ proxmox_storage }}:cloudinit \ + --boot c --bootdisk scsi0 \ + --serial0 socket --vga serial0 + + - name: Convert VM to template + ansible.builtin.shell: "qm template {{ proxmox_template_vm_id }}" + + - name: Stop and destroy LXC build container + ansible.builtin.shell: "pct stop {{ lxc_id }} && pct destroy {{ lxc_id }} --purge" + ignore_errors: true + + - ansible.builtin.debug: + msg: "✅ Debian Cloud-Init template {{ template_name }} (VMID {{ proxmox_template_vm_id }}) created successfully!" diff --git a/vars/debian_template.yml b/vars/debian_template.yml new file mode 100644 index 0000000..f26108e --- /dev/null +++ b/vars/debian_template.yml @@ -0,0 +1,8 @@ +--- +workdir: "/tmp/debian_template_build" +debian_image_url: "https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2" +image_name: "debian-13-genericcloud-amd64.qcow2" +template_name: "debian-13-cloudinit-template" +root_password: "debian" +proxmox_storage: "local-lvm" +proxmox_template_vm_id: 9000