├── LICENSE ├── samples ├── debian │ ├── debian-13-cloudinit.sh │ ├── debian-12-cloudinit.sh │ └── debian-12-cloudinit+docker.sh └── ubuntu │ ├── ubuntu-noble-cloudinit.sh │ └── ubuntu-noble-cloudinit+nvidia+runtime.sh └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 UntouchedWagons 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /samples/debian/debian-13-cloudinit.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -xe 4 | 5 | VMID="${VMID:-8000}" 6 | STORAGE="${STORAGE:-local-zfs}" 7 | 8 | IMG="debian-13-generic-amd64.qcow2" 9 | BASE_URL="https://cloud.debian.org/images/cloud/trixie/latest" 10 | EXPECTED_SHA=$(wget -qO- "$BASE_URL/SHA512SUMS" | awk '/'$IMG'/{print $1}') 11 | 12 | download() { 13 | wget -q "$BASE_URL/$IMG" 14 | } 15 | 16 | verify() { 17 | sha512sum "$IMG" | awk '{print $1}' 18 | } 19 | 20 | [ ! -f "$IMG" ] && download 21 | 22 | ACTUAL_SHA=$(verify) 23 | 24 | if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 25 | rm -f "$IMG" 26 | download 27 | ACTUAL_SHA=$(verify) 28 | [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ] && exit 1 29 | fi 30 | 31 | rm -f debian-13-generic-amd64-resized.qcow2 32 | cp debian-13-generic-amd64.qcow2 debian-13-generic-amd64-resized.qcow2 33 | qemu-img resize debian-13-generic-amd64-resized.qcow2 8G 34 | 35 | sudo qm destroy $VMID || true 36 | sudo qm create $VMID --name "debian-13-template" --ostype l26 \ 37 | --memory 1024 --balloon 0 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \ 40 | --cpu x86-64-v2-AES --cores 1 --numa 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0,mtu=1 43 | sudo qm importdisk $VMID debian-13-generic-amd64-resized.qcow2 $STORAGE 44 | sudo qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on 45 | sudo qm set $VMID --boot order=virtio0 46 | sudo qm set $VMID --scsi1 $STORAGE:cloudinit 47 | 48 | cat << EOF | sudo tee /var/lib/vz/snippets/debian-13.yaml 49 | #cloud-config 50 | runcmd: 51 | - apt-get update 52 | - apt-get install -y qemu-guest-agent 53 | - reboot 54 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 55 | EOF 56 | 57 | sudo qm set $VMID --cicustom "vendor=local:snippets/debian-13.yaml" 58 | sudo qm set $VMID --tags debian-template,debian-13,cloudinit 59 | sudo qm set $VMID --ciuser $USER 60 | sudo qm set $VMID --sshkeys ~/.ssh/authorized_keys 61 | sudo qm set $VMID --ipconfig0 ip=dhcp 62 | sudo qm template $VMID 63 | -------------------------------------------------------------------------------- /samples/debian/debian-12-cloudinit.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -xe 4 | 5 | VMID="${VMID:-8000}" 6 | STORAGE="${STORAGE:-local-zfs}" 7 | 8 | IMG="debian-12-generic-amd64.qcow2" 9 | BASE_URL="https://cloud.debian.org/images/cloud/bookworm/latest" 10 | EXPECTED_SHA=$(wget -qO- "$BASE_URL/SHA512SUMS" | awk '/'$IMG'/{print $1}') 11 | 12 | download() { 13 | wget -q "$BASE_URL/$IMG" 14 | } 15 | 16 | verify() { 17 | sha512sum "$IMG" | awk '{print $1}' 18 | } 19 | 20 | [ ! -f "$IMG" ] && download 21 | 22 | ACTUAL_SHA=$(verify) 23 | 24 | if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 25 | rm -f "$IMG" 26 | download 27 | ACTUAL_SHA=$(verify) 28 | [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ] && exit 1 29 | fi 30 | 31 | rm -f debian-12-generic-amd64-resized.qcow2 32 | cp debian-12-generic-amd64.qcow2 debian-12-generic-amd64-resized.qcow2 33 | qemu-img resize debian-12-generic-amd64-resized.qcow2 8G 34 | 35 | sudo qm destroy $VMID || true 36 | sudo qm create $VMID --name "debian-12-template" --ostype l26 \ 37 | --memory 1024 --balloon 0 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \ 40 | --cpu x86-64-v2-AES --cores 1 --numa 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0,mtu=1 43 | sudo qm importdisk $VMID debian-12-generic-amd64-resized.qcow2 $STORAGE 44 | sudo qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on 45 | sudo qm set $VMID --boot order=virtio0 46 | sudo qm set $VMID --scsi1 $STORAGE:cloudinit 47 | 48 | cat << EOF | sudo tee /var/lib/vz/snippets/debian-12.yaml 49 | #cloud-config 50 | runcmd: 51 | - apt-get update 52 | - apt-get install -y qemu-guest-agent 53 | - reboot 54 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 55 | EOF 56 | 57 | sudo qm set $VMID --cicustom "vendor=local:snippets/debian-12.yaml" 58 | sudo qm set $VMID --tags debian-template,debian-12,cloudinit 59 | sudo qm set $VMID --ciuser $USER 60 | sudo qm set $VMID --sshkeys ~/.ssh/authorized_keys 61 | sudo qm set $VMID --ipconfig0 ip=dhcp 62 | sudo qm template $VMID 63 | -------------------------------------------------------------------------------- /samples/ubuntu/ubuntu-noble-cloudinit.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -xe 4 | 5 | VMID="${VMID:-8200}" 6 | STORAGE="${STORAGE:-local-zfs}" 7 | 8 | IMG="noble-server-cloudimg-amd64.img" 9 | BASE_URL="https://cloud-images.ubuntu.com/noble/current" 10 | EXPECTED_SHA=$(wget -qO- "$BASE_URL/SHA256SUMS" | awk '/'$IMG'/{print $1}') 11 | 12 | download() { 13 | wget -q "$BASE_URL/$IMG" 14 | } 15 | 16 | verify() { 17 | sha256sum "$IMG" | awk '{print $1}' 18 | } 19 | 20 | [ ! -f "$IMG" ] && download 21 | 22 | ACTUAL_SHA=$(verify) 23 | 24 | if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 25 | rm -f "$IMG" 26 | download 27 | ACTUAL_SHA=$(verify) 28 | [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ] && exit 1 29 | fi 30 | 31 | rm -f noble-server-cloudimg-amd64-resized.img 32 | cp noble-server-cloudimg-amd64.img noble-server-cloudimg-amd64-resized.img 33 | qemu-img resize noble-server-cloudimg-amd64-resized.img 8G 34 | 35 | sudo qm destroy $VMID || true 36 | sudo qm create $VMID --name "ubuntu-noble-template" --ostype l26 \ 37 | --memory 1024 --balloon 0 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \ 40 | --cpu host --socket 1 --cores 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0 43 | sudo qm importdisk $VMID noble-server-cloudimg-amd64-resized.img $STORAGE 44 | sudo qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on 45 | sudo qm set $VMID --boot order=virtio0 46 | sudo qm set $VMID --scsi1 $STORAGE:cloudinit 47 | 48 | cat << EOF | sudo tee /var/lib/vz/snippets/ubuntu.yaml 49 | #cloud-config 50 | runcmd: 51 | - apt-get update 52 | - apt-get install -y qemu-guest-agent 53 | - systemctl enable ssh 54 | - reboot 55 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 56 | EOF 57 | 58 | sudo qm set $VMID --cicustom "vendor=local:snippets/ubuntu.yaml" 59 | sudo qm set $VMID --tags ubuntu-template,noble,cloudinit 60 | sudo qm set $VMID --ciuser $USER 61 | sudo qm set $VMID --sshkeys ~/.ssh/authorized_keys 62 | sudo qm set $VMID --ipconfig0 ip=dhcp 63 | sudo qm template $VMID 64 | -------------------------------------------------------------------------------- /samples/ubuntu/ubuntu-noble-cloudinit+nvidia+runtime.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -xe 4 | 5 | VMID="${VMID:-8202}" 6 | STORAGE="${STORAGE:-local-zfs}" 7 | 8 | IMG="noble-server-cloudimg-amd64.img" 9 | BASE_URL="https://cloud-images.ubuntu.com/noble/current" 10 | EXPECTED_SHA=$(wget -qO- "$BASE_URL/SHA256SUMS" | awk '/'$IMG'/{print $1}') 11 | 12 | download() { 13 | wget -q "$BASE_URL/$IMG" 14 | } 15 | 16 | verify() { 17 | sha256sum "$IMG" | awk '{print $1}' 18 | } 19 | 20 | [ ! -f "$IMG" ] && download 21 | 22 | ACTUAL_SHA=$(verify) 23 | 24 | if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 25 | rm -f "$IMG" 26 | download 27 | ACTUAL_SHA=$(verify) 28 | [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ] && exit 1 29 | fi 30 | 31 | rm -f noble-server-cloudimg-amd64-resized.img 32 | cp noble-server-cloudimg-amd64.img noble-server-cloudimg-amd64-resized.img 33 | qemu-img resize noble-server-cloudimg-amd64-resized.img 8G 34 | 35 | sudo qm destroy $VMID || true 36 | sudo qm create $VMID --name "ubuntu-noble-template-nvidia-runtime" --ostype l26 \ 37 | --memory 1024 --balloon 0 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \ 40 | --cpu host --socket 1 --cores 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0 43 | sudo qm importdisk $VMID noble-server-cloudimg-amd64-resized.img $STORAGE 44 | sudo qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on 45 | sudo qm set $VMID --boot order=virtio0 46 | sudo qm set $VMID --scsi1 $STORAGE:cloudinit 47 | 48 | cat << EOF | sudo tee /var/lib/vz/snippets/ubuntu-noble-runtime.yaml 49 | #cloud-config 50 | runcmd: 51 | - curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 52 | - curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list 53 | - apt-get update 54 | - apt-get install -y qemu-guest-agent nvidia-dkms-550-server nvidia-utils-550-server nvidia-container-runtime 55 | - systemctl enable ssh 56 | - reboot 57 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 58 | EOF 59 | 60 | sudo qm set $VMID --cicustom "vendor=local:snippets/ubuntu-noble-runtime.yaml" 61 | sudo qm set $VMID --tags ubuntu-template,noble,cloudinit,nvidia 62 | sudo qm set $VMID --ciuser $USER 63 | sudo qm set $VMID --sshkeys ~/.ssh/authorized_keys 64 | sudo qm set $VMID --ipconfig0 ip=dhcp 65 | sudo qm template $VMID 66 | -------------------------------------------------------------------------------- /samples/debian/debian-12-cloudinit+docker.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -xe 4 | 5 | VMID="${VMID:-8001}" 6 | STORAGE="${STORAGE:-local-zfs}" 7 | 8 | IMG="debian-12-generic-amd64.qcow2" 9 | BASE_URL="https://cloud.debian.org/images/cloud/bookworm/latest" 10 | EXPECTED_SHA=$(wget -qO- "$BASE_URL/SHA512SUMS" | awk '/'$IMG'/{print $1}') 11 | 12 | download() { 13 | wget -q "$BASE_URL/$IMG" 14 | } 15 | 16 | verify() { 17 | sha512sum "$IMG" | awk '{print $1}' 18 | } 19 | 20 | [ ! -f "$IMG" ] && download 21 | 22 | ACTUAL_SHA=$(verify) 23 | 24 | if [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ]; then 25 | rm -f "$IMG" 26 | download 27 | ACTUAL_SHA=$(verify) 28 | [ "$EXPECTED_SHA" != "$ACTUAL_SHA" ] && exit 1 29 | fi 30 | 31 | rm -f debian-12-generic-amd64-resized.qcow2 32 | cp debian-12-generic-amd64.qcow2 debian-12-generic-amd64-resized.qcow2 33 | qemu-img resize debian-12-generic-amd64-resized.qcow2 8G 34 | 35 | sudo qm destroy $VMID || true 36 | sudo qm create $VMID --name "debian-12-template-docker" --ostype l26 \ 37 | --memory 1024 --balloon 0 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \ 40 | --cpu x86-64-v2-AES --cores 1 --numa 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0,mtu=1 43 | sudo qm importdisk $VMID debian-12-generic-amd64-resized.qcow2 $STORAGE 44 | sudo qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on 45 | sudo qm set $VMID --boot order=virtio0 46 | sudo qm set $VMID --scsi1 $STORAGE:cloudinit 47 | 48 | cat << EOF | sudo tee /var/lib/vz/snippets/debian-12-docker.yaml 49 | #cloud-config 50 | runcmd: 51 | - apt-get update 52 | - apt-get install -y qemu-guest-agent gnupg 53 | - install -m 0755 -d /etc/apt/keyrings 54 | - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 55 | - chmod a+r /etc/apt/keyrings/docker.gpg 56 | - echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null 57 | - apt-get update 58 | - apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 59 | - reboot 60 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 61 | EOF 62 | 63 | sudo qm set $VMID --cicustom "vendor=local:snippets/debian-12-docker.yaml" 64 | sudo qm set $VMID --tags debian-template,debian-12,cloudinit,docker 65 | sudo qm set $VMID --ciuser $USER 66 | sudo qm set $VMID --sshkeys ~/.ssh/authorized_keys 67 | sudo qm set $VMID --ipconfig0 ip=dhcp 68 | sudo qm template $VMID 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Making a Ubuntu 24.04 VM Template for Proxmox and CloudInit 2 | 3 | This is a short guide for setting up a Ubuntu VM template in Proxmox using CloudInit in a scriptable manner. 4 | 5 | For this guide I have made a few assumptions: 6 | 7 | * You want your VMs to boot via UEFI as opposed to BIOS 8 | * Your Proxmox node's main storage is called `local-zfs` 9 | * You want to use Ubuntu 24.04 10 | * You have SSH keys stored in ~/.ssh/authorized_keys of your regular user's home folder 11 | 12 | ## Quick start 13 | If you want to quickly create an ubuntu VM template using this guide, you can run the following: 14 | ``` 15 | export VMID=8300 STORAGE=local-zfs 16 | curl -fsSL https://raw.githubusercontent.com/UntouchedWagons/Ubuntu-CloudInit-Docs/main/samples/ubuntu/ubuntu-noble-cloudinit.sh | bash 17 | ``` 18 | 19 | Other scripts are available in the [samples](./samples) directory, and can be used similarly to the above. 20 | 21 | ## The basics 22 | 23 | The first step is to enable support for snippets in the local dataset. Log into the Proxmox web UI and click Datacenter on the left, then Storage. Click local then Edit and a small window will pop up. In the Content drop down click on snippets, then OK. 24 | 25 | Now log into Proxmox via SSH so that we can download a cloud image for Ubuntu, then resize this image: 26 | 27 | #wget -q https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img 28 | #qemu-img resize noble-server-cloudimg-amd64.img 32G 29 | 30 | Notice that even though I'm resizing this image to be 32 gigabytes the file won't actually be 32 gigabytes in size, this is because the image is what's called a sparse file. The image starts out at around ~2GB but unless we resize the image now any cloned VMs won't have any storage. Feel free to change the 32G to 20, 80 or whatever you like. 31 | 32 | ## Creating the VM 33 | 34 | The next step is to create a basic VM that we'll build upon: 35 | 36 | #sudo qm create 8001 --name "ubuntu-2404-cloudinit-template" --ostype l26 \ 37 | --memory 1024 \ 38 | --agent 1 \ 39 | --bios ovmf --machine q35 --efidisk0 local-zfs:0,pre-enrolled-keys=0 \ 40 | --cpu host --sockets 1 --cores 1 \ 41 | --vga serial0 --serial0 socket \ 42 | --net0 virtio,bridge=vmbr0 43 | 44 | Feel free to change the 8001 to whatever you like, so long as you replace the 8001 in subsequent commands to whatever you chose. The memory chosen doesn't really matter because this particular VM won't start, make sure to adjust the amount of RAM for cloned VMs. `--agent ` enables the Qemu Guest Agent which is useful for all sorts of things like seeing the IP addresses of any interfaces. We'll set the CPU type to host (you almost always want this) with one socket and one core (remember to change the number of cores in cloned VMs). Next is the GPU, you can choose virtio instead of serial0 if you like but there's no need; serial gpu type does let you copy and paste which can be useful. Finally is the NIC, if you have a special bridge interface you want to choose change `vmbr0` to whatever you like. If you want to use a VLAN tag add `,tag=##` immediately after the bridge name (no spaces) 45 | 46 | ## Configuring hardware 47 | 48 | sudo qm importdisk 8001 noble-server-cloudimg-amd64.img local-zfs 49 | sudo qm set 8001 --scsihw virtio-scsi-pci --virtio0 local-zfs:vm-8001-disk-1,discard=on 50 | sudo qm set 8001 --boot order=virtio0 51 | sudo qm set 8001 --scsi1 local-zfs:cloudinit 52 | 53 | The first command imports that image we downloaded earlier, if your disk storage is not local-zfs (for example local-lvm) then replace it with whatever you wish. Next command attaches the disk to the VM. If your disk storage is not on SSDs (which it should be) omit `,discard=on`. The third command sets the boot order. Fourth adds the cloudinit pseudo-cdrom drive. 54 | 55 | ## Creating the vendor.yaml file for cloudinit 56 | mkdir /var/lib/vz/snippets 57 | cat << EOF | sudo tee /var/lib/vz/snippets/vendor.yaml 58 | #cloud-config 59 | runcmd: 60 | - apt update 61 | - apt install -y qemu-guest-agent 62 | - systemctl start qemu-guest-agent 63 | - reboot 64 | # Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772 65 | EOF 66 | 67 | This file performs two purposes, the first rather obvious (installing qemu-guest-agent) the second not so much. For some reason CloudInit starts *after* networking and thus you can't SSH or even ping the VM by the name you give it. This package is only run once so after this reboot you'll be able to use the VM. 68 | 69 | ## Configuring CloudInit 70 | 71 | sudo qm set 8001 --cicustom "vendor=local:snippets/vendor.yaml" 72 | sudo qm set 8001 --tags ubuntu-template,24.04,cloudinit 73 | sudo qm set 8001 --ciuser untouchedwagons 74 | sudo qm set 8001 --cipassword $(openssl passwd -6 $CLEARTEXT_PASSWORD) 75 | sudo qm set 8001 --sshkeys ~/.ssh/authorized_keys 76 | sudo qm set 8001 --ipconfig0 ip=dhcp 77 | 78 | The first command tells CI to use the vendor file we specified earler. The second can be skipped but adds decorative tags that show up in the Proxmox Web-UI. Cloned VMs inherit all these tags. The third specifies the user to create. The fourth sets the password. The fifth imports SSH public keys so you can SSH in. Finally the virtio NIC is set to DHCP, this is *supposed* to be the default but manual specifying is necessary. 79 | 80 | ## Finally: Converting to template 81 | 82 | sudo qm template 8001 83 | 84 | That's it! Your template is now ready to use. Clone this template as you wish (remember to adjust cores and RAM as needed) and start up the clone. After first boot Cloud-Init will kick in, create your user, install qemu-guest-agent and reboot. Once the reboot is complete you can SSH and use the VM however you like! 85 | 86 | ## Sample scripts 87 | 88 | In the samples folder I have included some pre-made shell scripts to create proxmox templates for you. At the top of each file are two environment variables that will need to be adjusted to how proxmox is set up. 89 | 90 | ## Thanks 91 | 92 | Thanks to ilude for telling me what command is needed to set the CI password. 93 | --------------------------------------------------------------------------------