Are you tired of manually creating VMs in Proxmox every time you need a new Ubuntu server? I’ll show you how to create a Ubuntu 24.04 Cloud-Init template in Proxmox using a simple Makefile in this guide. This automation will save you valuable time and ensure consistency across your VM deployments.
Deep Dive into the Makefile
Let’s break down each component of our Makefile to understand exactly what’s happening at each step.
GIT: https://github.com/thiagousa/youtube/blob/main/31/Makefile
Variables Configuration
VM_ID=6000
VM_NAME=ubuntu-24-04-cloud-init-template
IMAGE_URL=https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
IMAGE_NAME=noble-server-cloudimg-amd64.img
STORAGE=local
DISK_SIZE=50G
BRIDGE=vmbr0
VM_ID
: Unique identifier for your VM in Proxmox (must be unique across your cluster)VM_NAME
: Descriptive name for your templateIMAGE_URL
: Direct link to Ubuntu’s cloud imageIMAGE_NAME
: Local filename for the downloaded imageSTORAGE
: Proxmox storage location (default is ‘local’)DISK_SIZE
: Final size of the VM disk after expansionBRIDGE
: Network bridge for VM connectivity (default is vmbr0)
Step 0: Installing Required Tools
0_install_tools:
apt install libguestfs-tools -y
This step installs libguestfs-tools
, which provides essential utilities for manipulating disk images. The -y
flag automatically accepts installation prompts.
Step 1: Preparing the Directory
1_prepare_dir:
mkdir -p template
Creates a ‘template’ directory for our working files. The -p
flag prevents errors if the directory already exists.
Step 2: Downloading the Cloud Image
2_download_image: 1_prepare_dir
cd template && wget $(IMAGE_URL)
- Depends on
1_prepare_dir
to ensure the directory exists - Changes to the template directory
- Downloads the Ubuntu cloud image using wget
- Uses
$(IMAGE_URL)
variable for the download link
Step 3: Customizing the Image
3_customize_image: 2_download_image
cd template && virt-customize --add $(IMAGE_NAME) --install qemu-guest-agent
- Depends on
2_download_image
to ensure the image is available - Uses
virt-customize
to modify the image - Installs qemu-guest-agent for better VM management capabilities
- The
--add
flag specifies which image to modify
Step 4: Creating the VM
4_create_vm: 3_customize_image
qm create $(VM_ID) --name $(VM_NAME) --numa 0 --ostype l26 --cpu cputype=host --cores 4 --sockets 2 --memory 6144 --net0 virtio,bridge=$(BRIDGE)
- Creates a new VM with specific hardware configurations:
--numa 0
: Disables NUMA (Non-Uniform Memory Access)--ostype l26
: Specifies Linux 2.6/3.x/4.x kernel--cpu cputype=host
: Uses host CPU type for best performance--cores 4
: Allocates 4 CPU cores--sockets 2
: Sets 2 CPU sockets--memory 6144
: Allocates 6GB RAM--net0
: Configures the first network interface with virtio driver
Step 5: Importing the Disk
5_import_disk: 4_create_vm
cd template && qm importdisk $(VM_ID) $(IMAGE_NAME) $(STORAGE)
- Imports the customized cloud image as a disk for the VM
- Uses the specified storage location
- Creates a new disk with the VM ID
Step 6: Configuring the VM
6_configure_vm: 5_import_disk
qm set $(VM_ID) --scsihw virtio-scsi-pci --scsi0 $(STORAGE):$(VM_ID)/vm-$(VM_ID)-disk-0.raw
qm set $(VM_ID) --ide2 $(STORAGE):cloudinit
qm set $(VM_ID) --boot c --bootdisk scsi0
qm set $(VM_ID) --serial0 socket --vga serial0
qm set $(VM_ID) --agent enabled=1
Multiple important configurations:
- Sets up virtio-scsi-pci storage controller and attaches the imported disk
- Configures Cloud-Init drive on IDE2
- Sets boot order to use the SCSI disk
- Configures serial console
- Enables QEMU guest agent
Step 7: Resizing the Disk
7_resize_disk: 6_configure_vm
qm disk resize $(VM_ID) scsi0 +$(DISK_SIZE)
- Expand the disk to the specified size (50G)
- Uses the
+
to indicate additional space rather than absolute size
Step 8: Creating the Template
8_create_template: 7_resize_disk
qm template $(VM_ID)
- Converts the configured VM into a template
- After this step, the VM can’t be started but can be cloned
Step 9: Cleanup Option
9_clean:
rm -rf template
- Optional cleanup step to remove the working directory
- Useful for saving space after template creation
Phony Targets
.PHONY: all 0_install_tools 1_prepare_dir 2_download_image 3_customize_image 4_create_vm 5_import_disk 6_configure_vm 7_resize_disk 8_exit_shell 9_create_template 10_clean
- Declares all targets as phony
- Ensures Make runs commands even if a file with the same name exists
- Prevents conflicts with actual files/directories
Template Usage Tips
After creating your template, you can clone it using:
qm clone <template_vm_id> <new_vm_id> --name <new_vm_name>
For Cloud-Init configuration, you can set parameters like:
qm set <new_vm_id> --ciuser your_username
qm set <new_vm_id> --cipassword your_password
qm set <new_vm_id> --ipconfig0 ip=dhcp
The process will execute all steps automatically, creating your template.
Creating VMs from the Template
To create a new VM from your template:
- Go to your Proxmox web interface
- Right-click the template
- Select “Clone”
- Choose “Linked Clone” for space efficiency or “Full Clone” for independent VMs
- Configure Cloud-Init options (network, SSH keys, etc.)
- Start your new VM
Benefits of Using This Approach
- Consistency: Every VM created from this template will have the same base configuration
- Speed: Create new VMs in seconds instead of minutes
- Automation: Eliminate manual steps and reduce human error
- Resource Efficiency: Linked clones save storage space
- Maintainability: It is easy to update the template when needed
Conclusion
Using this automated approach with Make and Cloud-Init can streamline your VM creation process in Proxmox. The template system provides a solid foundation for deploying consistent, well-configured Ubuntu servers in your home lab or production environment.
Feel free to modify the Makefile variables to suit your needs, such as changing the VM ID, memory allocation, or disk size. Happy virtualization!