6 min read5 hours ago
–
Overview:
In the previous phase, we set up Proxmox and made a test VM. Manually creating each new VM takes too much time. Proxmox VM templates help with this. They are ready-made VMs with the OS installed and set up, so you can quickly clone them.
If you need several templates for different tasks, like one with Docker, building each by hand gets repetitive. HashiCorp Packer solves this problem. It’s an open-source tool that automates making consistent VM templates for many platforms, including Proxmox.
In this post, you will learn:
- How to create VM templates in Proxmox (the manual way).
- What Packer is and how it works.
- How to automate VM images (te…
6 min read5 hours ago
–
Overview:
In the previous phase, we set up Proxmox and made a test VM. Manually creating each new VM takes too much time. Proxmox VM templates help with this. They are ready-made VMs with the OS installed and set up, so you can quickly clone them.
If you need several templates for different tasks, like one with Docker, building each by hand gets repetitive. HashiCorp Packer solves this problem. It’s an open-source tool that automates making consistent VM templates for many platforms, including Proxmox.
In this post, you will learn:
- How to create VM templates in Proxmox (the manual way).
- What Packer is and how it works.
- How to automate VM images (template) creation using Packer with the official Proxmox integration.
Terminology:
- Template: In Proxmox, a template is a non-running VM used as a base for cloning new VMs (full or linked clones). Clones inherit everything from the template (disks, packages, and configurations) for fast, identical deployments.
- Full Clone: Creates a complete, independent copy of the template’s disk. It uses more storage but is fully isolated (changes to the clone don’t affect the template or other clones). Ideal for production where you want no shared dependencies.
- Linked Clone: Creates a lightweight copy that shares the base disk with the template (using snapshot/differencing disks). It uses minimal additional storage and deploys faster, but requires the original template to remain intact. Great for testing or when storage is limited.
- Golden Image: A secure, pre-configured base template with updates applied, tools installed (e.g., QEMU guest agent), and hardening. Ensuring consistency and production-readiness.
- Cloud-Init: An industry-standard tool for initializing instances at boot time (e.g., setting users, SSH keys, network config). Packer templates often enable cloud-init for per-VM customization later.
- Builder: The Packer plugin (or integration) that handles creating the image for a specific platform (e.g.,
proxmox-cloneorproxmox-isofor Proxmox). - Source: In Packer HCL templates, a block that defines the configuration for a builder (replacing the older “builders” array). Sources are reusable across multiple builds.
- Provisioner: In Packer, a component that runs inside the temporary VM during the build process to install software, configure settings, or run scripts (e.g., shell provisioner for apt installs).
- Build: The top-level Packer process or block that combines one or more sources, runs provisioners, and optionally post-processors to produce final artifacts (in our case, a Proxmox template).
- Post-Processor: An optional Packer component that runs after the build to process the artifact (e.g., compressing, uploading, or generating a manifest).
What is HashiCorp Configuration Language (HCL):
HCL (HashiCorp Configuration Language) is a declarative, human-readable configuration format created by HashiCorp. It powers tools like Packer, Terraform, Vault, and Nomad. HCL is designed to be both easy for humans to read/write and safe for machines to parse — supporting comments, variables, expressions, and structured data while being JSON-compatible under the hood.
Modern Packer uses HCL2 (version 2), which introduces blocks, improved variable handling, and better error messages.
Simple HCL Example (a minimal variable and source block):
# Define a variable with a default valuevariable "instance_count" { type = number default = 3 description = "Number of instances to create"}# A reusable source block for Proxmoxsource "proxmox-clone" "base_ubuntu" { clone_vm_id = 9000 node = "pve-node-01"# Use the variable in an expression template_name = "ubuntu-template-${var.instance_count}"}# Comments like this are allowed!
How Packer Works:
Packer takes a single declarative HCL template as input and produces one or more machine images (in our case, Proxmox templates) as output. The workflow is parallelizable, reproducible, and platform-agnostic.
Here’s the detailed step-by-step process:
- Read the Template: Packer parses your HCL file, validates syntax, and loads required plugins (the Proxmox plugin in our case).
- Create Temporary Resources: Using the specified builder, Packer connects to Proxmox via API and creates a temporary VM (either from an ISO
proxmox-isoor by cloning a base VM/templateproxmox-clone, both examples are found inmy repo). - Boot and Connect: The temporary VM boots, and Packer establishes a communicator (using SSH, usually) to access it.
- Run Provisioners: Packer executes your defined provisioners sequentially inside the VM (e.g., shell scripts to update packages, install Docker, or run Ansible playbooks).
- Cleanup and Halt: Optional cleanup steps run, then the VM shuts down gracefully.
- Convert to Artifact: The VM is converted into a reusable template (or other format, like AMI for AWS).
- Post-Processing (Optional): Compress, upload, or manifest the artifact.
Press enter or click to view image in full size
Packer workflow
Key Proxmox builders (as of Packer 1.14.3):
- proxmox-iso: Starts from an ISO for full OS installation (slower, highly customizable).
- proxmox-clone: Faster — clones an existing cloud-init-enabled base and applies changes.
- More integrations can be found in the official docs.
The entire process is idempotent, version-controlled, and repeatable.
How to create VM templates in Proxmox (the manual way):
Before diving into automation, let’s understand the traditional approach:
- Create a VM via the Proxmox webUI (check previous post).
- Perform OS installation, and necessary configuration (updating the system, installing tools…etc). Shut down the VM.
- Using the Web UI
Press enter or click to view image in full size
How to shutdown a VM, ig?
- Using the CLI:
qm shutdown <vm_id>
3. Enable cloud-init (cloud-init must be installed on the VM).
- Web UI
Press enter or click to view image in full size
Adding a Cloud-Init Drive
- Using the CLI:
qm set <vm_id> - ide0 local-lvm:cloudinit
4. Convert the VM to a template.
- Using the Web UI: (right click on the VM, then convert to template)
Press enter or click to view image in full size
Convert the VM into a Template
- Using the CLI
qm template <vm_id>
5. You can clone a VM template by right-clicking on the template and clicking clone:
- Using WebUI
Press enter or click to view image in full size
How to Clone a VM from a Template
Press enter or click to view image in full size
Clone options
- Using the CLI:
qm clone <template-id> <vm-id> - name vm-from-template - full # Fullqm clone <template-id> <vm-id> - name vm-linked - linked # Linked
This works for one-offs but is time-consuming and inconsistent for multiple templates.
Proxmox Setup:
Create A Packer user:
Trying to follow security best practices at all times, we want a user with “least privilege” access to the Proxmox API to do what’s needed to setup a VM and no more.
- Login to your Proxmox web GUI as
root - Add a user (I called it “Packer”) .
Press enter or click to view image in full size
Add user
Press enter or click to view image in full size
Add user options
3. Add User Permissions (PVEAdmin) to the user.
Press enter or click to view image in full size
User permissions
Press enter or click to view image in full size
User permissions settings
Create API Token
- Login to your Proxmox web GUI as
root. - Use new
packeruser, API Token, no expiry, copy secret.
Press enter or click to view image in full size
Creating an API token
3. Ensure Privilege Separation is not checked; otherwise, this token doesn’t get the packer users group permissions.
Press enter or click to view image in full size
Creating an API token settings
Press enter or click to view image in full size
Token
How to create VM templates in Proxmox using Packer (proxmox-iso Builder):
For full control (unattended installs, custom partitions), use proxmox-iso. It’s longer (full OS install) but powerful.
I’ve got a complete working example in the repo—check it out and tweak for your needs.
Next Phase:
Now that we’ve automated the provisioning of VM templates, we need to address the other issue, deploying tons of VMs, which is both time-consuming and error prone. That’s why Terraform/OpenTofu.