feat ✨: Added new feature to generate Debian VM templates and deploy clones
This commit introduces a new feature that allows users to create Debian VM templates and deploy clones. The feature includes options for customizing the template, such as making it a template or creating clones from it.
This commit is contained in:
53
defaults/main.yml
Normal file
53
defaults/main.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
vm_id: 150
|
||||
hostname: debian-template-base
|
||||
|
||||
memory: 4096
|
||||
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"
|
||||
|
||||
packages:
|
||||
- qemu-guest-agent
|
||||
- curl
|
||||
- htop
|
||||
|
||||
ci_user: debian
|
||||
ci_password: "SecurePass123"
|
||||
ssh_key_path: "~/.ssh/id_rsa.pub"
|
||||
|
||||
resize_disk: true
|
||||
resize_size: "16G"
|
||||
|
||||
gpu_passthrough: false
|
||||
gpu_device: "0000:01:00.0"
|
||||
virtio_gpu: false
|
||||
|
||||
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
|
||||
clones:
|
||||
- id: 301
|
||||
hostname: app01
|
||||
ip: "192.168.1.81/24"
|
||||
gateway: "192.168.1.1"
|
||||
|
||||
- id: 302
|
||||
hostname: app02
|
||||
ip: "192.168.1.82/24"
|
||||
gateway: "192.168.1.1"
|
||||
140
tasks/main.yml
Normal file
140
tasks/main.yml
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
- name: Create a Debian VM template and optionally deploy clones
|
||||
hosts: localhost
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
|
||||
##################################################################
|
||||
# 1. Ensure Debian GenericCloud Image Exists
|
||||
##################################################################
|
||||
- name: Check for Debian image
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2"
|
||||
register: debian_img
|
||||
|
||||
- name: Download GenericCloud qcow2
|
||||
ansible.builtin.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
|
||||
##################################################################
|
||||
- name: Create VM
|
||||
ansible.builtin.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"
|
||||
|
||||
##################################################################
|
||||
# 3. Optional UEFI + Secure Boot + TPM 2.0
|
||||
##################################################################
|
||||
- name: Enable UEFI + Secure Boot + TPM (optional)
|
||||
ansible.builtin.command: >
|
||||
qm set {{ vm_id }}
|
||||
--bios ovmf
|
||||
--efidisk0 {{ storage }}:1,pre-enrolled-keys=1
|
||||
--tpmstate0 {{ storage }}:1,size=4M,version=v2.0
|
||||
when: enable_tpm | default(false)
|
||||
|
||||
##################################################################
|
||||
# 4. Disk Import
|
||||
##################################################################
|
||||
- name: Import qcow2 disk
|
||||
ansible.builtin.command: >
|
||||
qm importdisk {{ vm_id }}
|
||||
/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2
|
||||
{{ storage }}
|
||||
|
||||
- name: Attach imported disk
|
||||
ansible.builtin.command: >
|
||||
qm set {{ vm_id }}
|
||||
--scsihw virtio-scsi-pci
|
||||
--scsi0 {{ storage }}:vm-{{ vm_id }}-disk-0
|
||||
|
||||
##################################################################
|
||||
# 5. Optional Disk Resize
|
||||
##################################################################
|
||||
- name: Resize disk
|
||||
ansible.builtin.command: >
|
||||
qm resize {{ vm_id }} scsi0 {{ resize_size }}
|
||||
when: resize_disk | default(false)
|
||||
|
||||
##################################################################
|
||||
# 6. Optional GPU Passthrough
|
||||
##################################################################
|
||||
- name: PCI GPU passthrough
|
||||
ansible.builtin.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
|
||||
when: virtio_gpu | default(false)
|
||||
|
||||
##################################################################
|
||||
# 7. Cloud-Init Templates
|
||||
##################################################################
|
||||
- name: Create Cloud-Init vendor-data
|
||||
ansible.builtin.template:
|
||||
src: cloudinit_vendor.yaml.j2
|
||||
dest: "/var/lib/vz/snippets/{{ vm_id }}-vendor.yaml"
|
||||
|
||||
- name: Create Cloud-Init user-data
|
||||
ansible.builtin.template:
|
||||
src: cloudinit_userdata.yaml.j2
|
||||
dest: "/var/lib/vz/snippets/{{ vm_id }}-user.yaml"
|
||||
|
||||
##################################################################
|
||||
# 8. Apply Cloud-Init
|
||||
##################################################################
|
||||
- name: Apply Cloud-Init config
|
||||
ansible.builtin.command: >
|
||||
qm set {{ vm_id }}
|
||||
--ciuser {{ ci_user }}
|
||||
--cipassword '{{ ci_password }}'
|
||||
--sshkeys "{{ lookup('file', ssh_key_path) }}"
|
||||
--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
|
||||
##################################################################
|
||||
- name: Convert VM to template
|
||||
ansible.builtin.command: qm template {{ vm_id }}
|
||||
when: make_template | default(false)
|
||||
|
||||
##################################################################
|
||||
# 10. Optionally Create Cloud-Init Clones from Template
|
||||
##################################################################
|
||||
- name: Create clones from template (optional)
|
||||
when: create_clones | default(false)
|
||||
loop: "{{ clones }}"
|
||||
loop_control:
|
||||
loop_var: clone
|
||||
|
||||
block:
|
||||
|
||||
- name: Clone VM from template
|
||||
ansible.builtin.command: >
|
||||
qm clone {{ vm_id }} {{ clone.id }} --name {{ clone.hostname }}
|
||||
|
||||
- name: Apply cloud-init settings for clone
|
||||
ansible.builtin.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 }}
|
||||
24
templates/cloudinit_userdata.yaml.j2
Normal file
24
templates/cloudinit_userdata.yaml.j2
Normal file
@@ -0,0 +1,24 @@
|
||||
#cloud-config
|
||||
|
||||
users:
|
||||
- name: {{ ci_user }}
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
groups: users, admin, sudo
|
||||
shell: /bin/bash
|
||||
lock_passwd: false
|
||||
passwd: {{ ci_password | password_hash('sha512') }}
|
||||
ssh_authorized_keys:
|
||||
- {{ lookup('file', ssh_key_path) }}
|
||||
|
||||
chpasswd:
|
||||
expire: false
|
||||
|
||||
ssh_pwauth: true
|
||||
|
||||
timezone: "{{ timezone | default('UTC') }}"
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
runcmd:
|
||||
- echo "Cloud-init user-data executed for {{ hostname }}"
|
||||
14
templates/cloudinit_vendor.yaml.j2
Normal file
14
templates/cloudinit_vendor.yaml.j2
Normal file
@@ -0,0 +1,14 @@
|
||||
#cloud-config
|
||||
packages:
|
||||
{% for pkg in packages %}
|
||||
- {{ pkg }}
|
||||
{% endfor %}
|
||||
|
||||
{% if dns %}
|
||||
manage_resolve_conf: true
|
||||
resolv_conf:
|
||||
nameservers:
|
||||
{% for ns in dns %}
|
||||
- {{ ns }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user