Skip to content

Instantly share code, notes, and snippets.

@chriswayg
Last active May 1, 2024 20:47
Show Gist options
  • Star 69 You must be signed in to star a gist
  • Fork 39 You must be signed in to fork a gist
  • Save chriswayg/43fbea910e024cbe608d7dcb12cb8466 to your computer and use it in GitHub Desktop.
Save chriswayg/43fbea910e024cbe608d7dcb12cb8466 to your computer and use it in GitHub Desktop.
This script will download a cloud image of many Linux distros and create a Proxmox 6 KVM template from it.
#!/bin/bash
set -o errexit
clear
printf "\n*** This script will download a cloud image and create a Proxmox VM template from it. ***\n\n"
### HOW TO USE
### Pre-req:
### - run on a Proxmox 6 server
### - a dhcp server should be active on vmbr1
###
### - fork the gist and adapt the defaults (especially SSHKEY) as needed
### - download latest version of the script:
### curl wget https://gist.githubusercontent.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466/raw/create-cloud-template.sh > /usr/local/bin/create-cloud-template.sh && chmod -v +x /usr/local/bin/create-cloud-template.sh
### - (optionally) prepare a cloudinit user-config.yml in the working directory
### this could be copied and modified from the cloudinit user dump at the end of this script
### - run the script:
### $ create-cloud-template.sh
### - clone the finished template from the Proxmox GUI and test
###
### NOTES:
### - links to cloud images:
### Directory: https://docs.openstack.org/image-guide/obtain-images.html
### Debian http://cdimage.debian.org/cdimage/openstack/
### Ubuntu http://cloud-images.ubuntu.com/
### CentOS: http://cloud.centos.org/centos/7/images/
### Fedora: https://alt.fedoraproject.org/cloud/
### SUSE 15 SP1 JeOS: https://download.suse.com/Download?buildid=OE-3enq3uys~
### CirrOS http://download.cirros-cloud.net/
### CoreOS (EOL 05.2020): https://stable.release.core-os.net/amd64-usr/current/
### Flatcar (CoreOS fork): https://stable.release.flatcar-linux.net/amd64-usr/current/
### Gentoo: http://gentoo.osuosl.org/experimental/amd64/openstack
### Arch (also Gentoo): https://linuximages.de/openstack/arch/
### Alpine: https://github.com/chriswayg/packer-qemu-cloud/
### RancherOS: https://github.com/rancher/os/releases (also includes Proxmox iso version)
###
### - most links will download the latest current (stable) version of the OS
### - older cloud-init versions do not support hashed passwords
## TODO
## - verify authenticity of downloaded images using hash or GPG
printf "* Available templates to generate:\n 2) Debian 9\n 3) Debian 10\n 4) Ubuntu 18.04\n 5) Centos 7\n 6) CoreOS/Flatcar\n 7) Arch\n 8) Alpine 3.11\n 9) RancherOS 1.5.5\n\n"
read -p "* Enter number of distro to use: " OSNR
# defaults which are used for most templates
RESIZE=+30G
MEMORY=2048
BRIDGE=vmbr1
USERCONFIG_DEFAULT=none # cloud-init-config.yml
CITYPE=nocloud
SNIPPETSPATH=/var/lib/vz/snippets
SSHKEY=~/.ssh/2019_id_rsa.pub # ~/.ssh/id_rsa.pub
NOTE=""
case $OSNR in
2)
OSNAME=debian9
VMID_DEFAULT=51100
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
VMIMAGE=debian-9-openstack-amd64.qcow2
NOTE="\n## Default user is 'debian'\n## NOTE: Setting a password via cloud-config does not work.\n"
printf "$NOTE\n"
wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-9/$VMIMAGE
;;
3)
OSNAME=debian10
VMID_DEFAULT=51200
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
VMIMAGE=debian-10-openstack-amd64.qcow2
NOTE="\n## Default user is 'debian'\n"
printf "$NOTE\n"
wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-10/$VMIMAGE
;;
4)
OSNAME=ubuntu1804
VMID_DEFAULT=52000
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
VMIMAGE=bionic-server-cloudimg-amd64.img
NOTE="\n## Default user is 'ubuntu'\n"
printf "$NOTE\n"
wget -P /tmp -N https://cloud-images.ubuntu.com/bionic/current/$VMIMAGE
;;
5)
OSNAME=centos7
VMID_DEFAULT=53100
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
RESIZE=+24G
VMIMAGE=CentOS-7-x86_64-GenericCloud.qcow2
NOTE="\n## Default user is 'centos'\n## NOTE: CentOS ignores hostname config.\n# use 'hostnamectl set-hostname centos7-cloud' inside VM\n"
printf "$NOTE\n"
wget -P /tmp -N http://cloud.centos.org/centos/7/images/$VMIMAGE
;;
6)
# - Proxmox creates a configdrive with the option: 'manage_etc_hosts: true'
# which causes an error in 'user-configdrive.service':
# 'Failed to apply cloud-config: Invalid option to manage_etc_hosts'
# There is no problem, when supplying a compatible 'user-config.yml'.
# - CoreOS needs 'configdrive2'
# - CoreOS is End of Life in 05.2020, use Flatcar instead
# https://github.com/coreos/coreos-cloudinit/blob/master/Documentation/config-drive.md
#
# OSNAME=coreos
# VMID_DEFAULT=54600
# read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
# VMID=${VMID:-$VMID_DEFAULT}
# RESIZE=+24G
# VMIMAGE=coreos_production_qemu_image.img.bz2
# CITYPE=configdrive2
# NOTE="\n## Default user is 'core'\n## NOTE: In CoreOS, setting a password via cloud-config does not seem to work!\n"
# printf "$NOTE\n"
# wget -P /tmp -N https://stable.release.core-os.net/amd64-usr/current/$VMIMAGE
OSNAME=flatcar
VMID_DEFAULT=54600
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
RESIZE=+24G
VMIMAGE=flatcar_production_qemu_image.img.bz2
CITYPE=configdrive2
NOTE="\n## Default user is 'coreos'\n## NOTE: Setting a password via cloud-config does not work.\n"
printf "$NOTE\n"
wget -P /tmp -N https://stable.release.flatcar-linux.net/amd64-usr/current/$VMIMAGE
;;
7)
OSNAME=arch
VMID_DEFAULT=54200
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
RESIZE=+29G
VMIMAGE=arch-openstack-LATEST-image-bootstrap.qcow2
NOTE="\n## Default user is 'arch'\n## NOTE: Setting a password via cloud-config does not work.\n# Resizing does not happen automatically inside the VM\n"
printf "$NOTE\n"
wget -P /tmp -N https://linuximages.de/openstack/arch/$VMIMAGE
;;
8)
OSNAME=alpine311
VMID_DEFAULT=54000
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
VMIMAGE=alpine-311-cloudimg-amd64.qcow2
NOTE="\n## Default user is 'alpine'\n## NOTE: Cloud-init on Alpine 3.11 is not able to apply network config.\n# Setting a password via cloud-config does not work.\n# CHANGE the default root passwword (root can only login via console).\n"
printf "$NOTE\n"
wget -P /tmp -N https://github.com/chriswayg/packer-proxmox-templates/releases/download/v1.6/$VMIMAGE
#cp -v /root/$VMIMAGE /tmp/ # for local testing
;;
9)
OSNAME=rancheros
VMID_DEFAULT=54400
read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
VMID=${VMID:-$VMID_DEFAULT}
VMIMAGE=rancheros-openstack.img
CITYPE=configdrive2
NOTE="\n## Default user is 'rancher'\n## NOTE: Setting a password via cloud-config does not work.\n# RancherOS does autologin on console.\n"
printf "$NOTE\n"
wget -P /tmp -N https://github.com/rancher/os/releases/download/v1.5.5/$VMIMAGE
;;
*)
printf "\n** Unknown OS number. Please use one of the above!\n"
exit 0
;;
esac
[[ $VMIMAGE == *".bz2" ]] \
&& printf "\n** Uncompressing image (waiting to complete...)\n" \
&& bzip2 -d --force /tmp/$VMIMAGE \
&& VMIMAGE=$(echo "${VMIMAGE%.*}") # remove .bz2 file extension from file name
# TODO: could prompt for the VM name
printf "\n** Creating a VM with $MEMORY MB using network bridge $BRIDGE\n"
qm create $VMID --name $OSNAME-cloud --memory $MEMORY --net0 virtio,bridge=$BRIDGE
printf "\n** Importing the disk in qcow2 format (as 'Unused Disk 0')\n"
qm importdisk $VMID /tmp/$VMIMAGE local -format qcow2
printf "\n** Attaching the disk to the vm using VirtIO SCSI\n"
qm set $VMID --scsihw virtio-scsi-pci --scsi0 /var/lib/vz/images/$VMID/vm-$VMID-disk-0.qcow2
printf "\n** Setting boot and display settings with serial console\n"
qm set $VMID --boot c --bootdisk scsi0 --serial0 socket --vga serial0
printf "\n** Using a dhcp server on $BRIDGE (or change to static IP)\n"
qm set $VMID --ipconfig0 ip=dhcp
#This would work in a bridged setup, but a routed setup requires a route to be added in the guest
#qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1
printf "\n** Creating a cloudinit drive managed by Proxmox\n"
qm set $VMID --ide2 local:cloudinit
printf "\n** Specifying the cloud-init configuration format\n"
qm set $VMID --citype $CITYPE
printf "#** Made with create-cloud-template.sh - https://gist.github.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
## TODO: Also ask for a network configuration. Or create a config with routing for a static IP
printf "\n*** The script can add a cloud-init configuration with users and SSH keys from a file in the current directory.\n"
read -p "Supply the name of the cloud-init-config.yml (this will be skipped, if file not found) [$USERCONFIG_DEFAULT]: " USERCONFIG
USERCONFIG=${USERCONFIG:-$USERCONFIG_DEFAULT}
if [ -f $PWD/$USERCONFIG ]
then
# The cloud-init user config file overrides the user settings done elsewhere
printf "\n** Adding user configuration\n"
cp -v $PWD/$USERCONFIG $SNIPPETSPATH/$VMID-$OSNAME-$USERCONFIG
qm set $VMID --cicustom "user=local:snippets/$VMID-$OSNAME-$USERCONFIG"
printf "#* cloud-config: $VMID-$OSNAME-$USERCONFIG\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
else
# The SSH key should be supplied either in the cloud-init config file or here
printf "\n** Skipping config file, as none was found\n\n** Adding SSH key\n"
qm set $VMID --sshkey $SSHKEY
printf "\n"
read -p "Supply an optional password for the default user (press Enter for none): " PASSWORD
[ ! -z "$PASSWORD" ] \
&& printf "\n** Adding the password to the config\n" \
&& qm set $VMID --cipassword $PASSWORD \
&& printf "#* a password has been set for the default user\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
printf "#- cloud-config used: via Proxmox\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
fi
# The NOTE is added to the Summary section of the VM (TODO there seems to be no 'qm' command for this)
printf "#$NOTE\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
printf "\n** Increasing the disk size\n"
qm resize $VMID scsi0 $RESIZE
printf "\n*** The following cloud-init configuration will be used ***\n"
printf "\n------------- User ------------------\n"
qm cloudinit dump $VMID user
printf "\n------------- Network ---------------\n"
qm cloudinit dump $VMID network
# convert the vm into a template (TODO make this optional)
qm template $VMID
printf "\n** Removing previously downloaded image file\n\n"
rm -v /tmp/$VMIMAGE
printf "$NOTE\n\n"
@zimmertr
Copy link

zimmertr commented Aug 20, 2020

Hello, with respect to Flatcar linux and your comments above , I can confirm that the manage_etc_hosts bug exists. But I can not replicate a successful build with cicustom. Can you share yours? Even things as simple as:

hostname: test

and

manage_etc_hosts: false
hostname: "test"
ssh_authorized_keys:
  - REDACTED

Don't work for me. I am never able to connect after the VM comes up and a VNC console shows that the hostname is set to localhost not test.

@xcnix
Copy link

xcnix commented Dec 21, 2020

Hello, with respect to Flatcar linux and your comments above , I can confirm that the manage_etc_hosts bug exists. But I can not replicate a successful build with cicustom. Can you share yours? Even things as simple as:

hostname: test

and

manage_etc_hosts: false
hostname: "test"
ssh_authorized_keys:
  - REDACTED

Don't work for me. I am never able to connect after the VM comes up and a VNC console shows that the hostname is set to localhost not test.

https://gist.github.com/aw/ce460c2100163c38734a83e09ac0439a
Did you try this method ?

@Oratorian
Copy link

Oratorian commented Dec 26, 2020

I modified this script a little bit.

Now you can set the used storage for the VM
You can also set the used format for the disk images
The node name is automaticly set since Proxmox uses the systems hostname as nodenames.
I also added a new menu for Ubuntu which will let you choose the version between 18.04 and 20.04.

https://gist.github.com/Oratorian/274bc106fec46787408cc1f4bd21bc74

@akong77
Copy link

akong77 commented May 4, 2021

Hello,
I use this script on debian 9.But the nameserver always use 127.0.0.1
How to fix it?

@akong77
Copy link

akong77 commented May 4, 2021

Hello,
Could support Centos8 and Ubuntu 20.04 LTS?

@meramsey
Copy link

meramsey commented Aug 8, 2021

please see my updated one with centos8 more ubuntu ones and also almalinux
https://gist.github.com/meramsey/aa759614cb5e387d8b88a0adfe77cc1d

Also there is alot of improvements that could be made to this such as enabling root login and adding in custom packages and naming the containers nicer. You really don't need to usually expand the disk until its deployed and if you use cloud-init then it will expand on first boot so there is no reason to normally make the template large in advance of when its used unless you got space to burn.

Also for more detail see:
https://whattheserver.com/proxmox-cloud-init-os-template-creation/

I need to make a script wrapper for this but you can get an idea of how easy it is with the below examples:

vm_id='1804'
cloud_img_url='https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img'
storage='local'
disk_format='qcow2'
image_name=${cloud_img_url##*/}
image_base_name=${image_name%.$disk_format}
image_template_name='Ubuntu-Server-18.04-LTS-Bionic-Beaver'  #${image_base_name//.x86_64/}
wget ${cloud_img_url}
# For rhel/centos use this instead atop,htop are not in main repo
#virt-customize --install cloud-init,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-customize --install cloud-init,atop,htop,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: [Tt]rue/disable_root: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: 1/disable_root: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: [Tt]rue/lock_passwd: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: 1/lock_passwd: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/ssh_pwauth:   0/ssh_pwauth:   1/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PasswordAuthentication no/PasswordAuthentication yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PermitRootLogin [Nn]o/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin [Yy]es/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/[#M]axAuthTries 6/MaxAuthTries 20/'
qm create ${vm_id} --memory 512 --ide0 local:cloudinit --ide2 none,media=cdrom --net0 virtio,bridge=vmbr0,firewall=1 --serial0 socket --scsihw virtio-scsi-single --onboot 1 --autostart 1 --agent enabled=1,fstrim_cloned_disks=1 --ciuser root --description ${image_name} --bootdisk virtio0 --name ${image_template_name} --ostype l26
qm importdisk ${vm_id} ${image_name} ${storage} --format ${disk_format}
qm set ${vm_id} --virtio0 ${storage}:${vm_id}/vm-${vm_id}-disk-0.${disk_format}
qm set ${vm_id} --boot c --bootdisk virtio0
qm template ${vm_id}



vm_id='2004'
cloud_img_url='https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img'
storage='local'
disk_format='qcow2'
image_name=${cloud_img_url##*/}
image_base_name=${image_name%.$disk_format}
image_template_name='Ubuntu-Server-20.04-LTS-Focal-Fossa'  #${image_base_name//.x86_64/}
wget ${cloud_img_url}
# For rhel/centos use this instead atop,htop are not in main repo
#virt-customize --install cloud-init,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-customize --install cloud-init,atop,htop,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: [Tt]rue/disable_root: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: 1/disable_root: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: [Tt]rue/lock_passwd: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: 1/lock_passwd: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/ssh_pwauth:   0/ssh_pwauth:   1/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PasswordAuthentication no/PasswordAuthentication yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PermitRootLogin [Nn]o/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin [Yy]es/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/[#M]axAuthTries 6/MaxAuthTries 20/'
qm create ${vm_id} --memory 512 --ide0 local:cloudinit --ide2 none,media=cdrom --net0 virtio,bridge=vmbr0,firewall=1 --serial0 socket --scsihw virtio-scsi-single --onboot 1 --autostart 1 --agent enabled=1,fstrim_cloned_disks=1 --ciuser root --description ${image_name} --bootdisk virtio0 --name ${image_template_name} --ostype l26
qm importdisk ${vm_id} ${image_name} ${storage} --format ${disk_format}
qm set ${vm_id} --virtio0 ${storage}:${vm_id}/vm-${vm_id}-disk-0.${disk_format}
qm set ${vm_id} --boot c --bootdisk virtio0
qm template ${vm_id}

vm_id='2010'
cloud_img_url='https://cloud-images.ubuntu.com/groovy/current/groovy-server-cloudimg-amd64.img'
storage='local'
disk_format='qcow2'
image_name=${cloud_img_url##*/}
image_base_name=${image_name%.$disk_format}
image_template_name='Ubuntu-Server-20.10-Groovy-Gorilla'  #${image_base_name//.x86_64/}
wget ${cloud_img_url}
# For rhel/centos use this instead atop,htop are not in main repo
#virt-customize --install cloud-init,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-customize --install cloud-init,atop,htop,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: [Tt]rue/disable_root: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: 1/disable_root: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: [Tt]rue/lock_passwd: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: 1/lock_passwd: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/ssh_pwauth:   0/ssh_pwauth:   1/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PasswordAuthentication no/PasswordAuthentication yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PermitRootLogin [Nn]o/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin [Yy]es/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/[#M]axAuthTries 6/MaxAuthTries 20/'
qm create ${vm_id} --memory 512 --ide0 local:cloudinit --ide2 none,media=cdrom --net0 virtio,bridge=vmbr0,firewall=1 --serial0 socket --scsihw virtio-scsi-single --onboot 1 --autostart 1 --agent enabled=1,fstrim_cloned_disks=1 --ciuser root --description ${image_name} --bootdisk virtio0 --name ${image_template_name} --ostype l26
qm importdisk ${vm_id} ${image_name} ${storage} --format ${disk_format}
qm set ${vm_id} --virtio0 ${storage}:${vm_id}/vm-${vm_id}-disk-0.${disk_format}
qm set ${vm_id} --boot c --bootdisk virtio0
qm template ${vm_id}



vm_id='2104'
cloud_img_url='https://cloud-images.ubuntu.com/hirsute/current/hirsute-server-cloudimg-amd64.img'
storage='local'
disk_format='qcow2'
image_name=${cloud_img_url##*/}
image_base_name=${image_name%.$disk_format}
image_template_name='Ubuntu-Server-21.04-Hirsute-Hippo'  #${image_base_name//.x86_64/}
wget ${cloud_img_url}
# For rhel/centos use this instead atop,htop are not in main repo
#virt-customize --install cloud-init,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-customize --install cloud-init,atop,htop,nano,vim,qemu-guest-agent,curl,wget -a ${image_name}
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: [Tt]rue/disable_root: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/disable_root: 1/disable_root: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: [Tt]rue/lock_passwd: False/'
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/lock_passwd: 1/lock_passwd: 0/' 
virt-edit -a ${image_name} /etc/cloud/cloud.cfg -e 's/ssh_pwauth:   0/ssh_pwauth:   1/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PasswordAuthentication no/PasswordAuthentication yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/PermitRootLogin [Nn]o/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin [Yy]es/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/'
virt-edit -a ${image_name} /etc/ssh/sshd_config -e 's/[#M]axAuthTries 6/MaxAuthTries 20/'
qm create ${vm_id} --memory 512 --ide0 local:cloudinit --ide2 none,media=cdrom --net0 virtio,bridge=vmbr0,firewall=1 --serial0 socket --scsihw virtio-scsi-single --onboot 1 --autostart 1 --agent enabled=1,fstrim_cloned_disks=1 --ciuser root --description ${image_name} --bootdisk virtio0 --name ${image_template_name} --ostype l26
qm importdisk ${vm_id} ${image_name} ${storage} --format ${disk_format}
qm set ${vm_id} --virtio0 ${storage}:${vm_id}/vm-${vm_id}-disk-0.${disk_format}
qm set ${vm_id} --boot c --bootdisk virtio0
qm template ${vm_id}

@modem7
Copy link

modem7 commented Apr 29, 2022

Heya,

Thank you very much for this!

I've made some changes so that passwords and VLANs can be added if needs be:

https://github.com/modem7/public_scripts/blob/master/Bash/Proxmox%20Scripts/create-jammy-cloud-template.sh

Albeit, this is purely for Ubuntu, but should be easily scalable to others.

@duven87
Copy link

duven87 commented Jan 16, 2023

How can I put multiple routes?

@modem7
Copy link

modem7 commented Jan 16, 2023

How can I put multiple routes?

# Create/Set vNIC
qm set $VMID --net0 virtio,bridge=${NET_BRIDGE}${VLAN:+,tag=$VLAN}
qm set $VMID --net1 virtio,bridge=${NET_BRIDGE}${VLAN:+,tag=$VLAN}
# Create/Set Cloud-Init vNIC settings
qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1
qm set $VMID --ipconfig1 ip=10.10.0.222/24,gw=10.10.0.1

The above has variables that are set in my script in the above comment, but they should be easy enough to figure out.

@duven87
Copy link

duven87 commented Jan 18, 2023

Thank you,
sorry, I am not very familiar with scripts.
But to create several routes with the same network interface and being in the same VLAN?
--ipconfig0 and --ipconfig1 have nothing to do with the interface or yes?
I can easily make several lines for each route leaving only net0?

qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1
qm set $VMID --ipconfig1 ip=10.10.0.222/24,gw=10.10.0.1

@modem7
Copy link

modem7 commented Jan 18, 2023

Thank you, sorry, I am not very familiar with scripts. But to create several routes with the same network interface and being in the same VLAN? --ipconfig0 and --ipconfig1 have nothing to do with the interface or yes? I can easily make several lines for each route leaving only net0?

qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1
qm set $VMID --ipconfig1 ip=10.10.0.222/24,gw=10.10.0.1

netX is the interface details (you might need to add a vlan tag as well).

qm set 100 --net0 virtio,bridge=vmbr1,tag=10
qm set 100 --net1 virtio,bridge=vmbr1,tag=20

image

ipconfigX is to configure the interface in cloud-init if you're using that.

qm set 100 --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1
qm set 100 --ipconfig1 ip=10.10.0.222/24,gw=10.10.0.1

image


You cannot define an IP address in the NIC settings in the hardware tab as IP addresses are dealt with by the VM. But you can set VLAN tags.
What you can do, if you use cloud-init is define what the IP address/subnet should be - although this is optional, but very useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment