Discovering Packer

In my journey to automate infrastructure, I stumbled upon Packer, a fascinating tool developed by HashiCorp. It's a free tool that has allowed me to create prebuilt images for various platforms like AWS, Azure, Digital Ocean, VirtualBox, Proxmox, and many other cloud providers or hypervisors.

What I love most about this command-line tool is that it lets me create custom images with:

I was blown away by how powerful it is for automating infrastructure deployment. Thanks to Packer, I can spin up my testing or development environments in no time. The coolest part? It works on every system: Windows, macOS, and Linux!

How I Got Packer Working with Proxmox

While exploring Packer, I found out it offers two different ways to work with Proxmox:

Proxmox Builders


Source: Official Packer Docs

For this guide, I chose to use proxmox-iso because it works perfectly with Proxmox VM templates.

My First Template: A Step-by-Step Experience

What I Wanted to Create

I set out to create a template based on Ubuntu 24.04 (Noble) with these specs:

Setting Up Packer

Installation

The first cool thing about Packer is that it doesn't need to be on the same machine as Proxmox. To install it, I followed the official documentation.

On my Linux machine, I used these commands:

wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install packer

File Organization

To save you some time, I've created a repository you can clone:

git clone https://github.com/LudovicARHIMAN/Packer-Templates.git

Here's how I organized the files:

.
├── README.md
├── credentials.pkr.hcl
└── ubuntu-server-noble
    ├── files
    │   └── 99-pve.cfg
    ├── http
    │   ├── meta-data
    │   └── user-data
    └── ubuntu-server-noble.pkr.hcl
You won't find the credentials.pkr.hcl file in the repo as it contains sensitive information. I excluded it with .gitignore for security reasons.

Create your own credentials.pkr.hcl file with this template:

proxmox_api_url = "https://0.0.0.0:8006/api2/json"  # Your Proxmox address
proxmox_api_token_id = "GENERATED_API_TOKEN-ID"  # Your token ID
proxmox_api_token_secret = "GENERATED_API_Secret"

Setting Up the API Token in Proxmox

To let Packer talk to Proxmox, we need to create an API token. Here's how I did it:

  1. In the Proxmox web interface, I went to Datacenter > Permissions > API Token
  2. Clicked on Add to create a new token
API Token Creation

Then, I updated my credentials.pkr.hcl file with my information:

proxmox_api_url = "https://pve.reverse9.xyz:8006/api2/json"  # My Proxmox server
proxmox_api_token_id = "root@pam!packer"  # My token ID
proxmox_api_token_secret = "my-secret-token-here"

Understanding the Configuration Files

The Main Template File

The file ubuntu-server-noble/ubuntu-server-noble.pkr.hcl is where the magic happens. Let me walk you through how I configured it:

1. The Essential Variables

variable "proxmox_api_url" {
    type = string
}

variable "proxmox_api_token_id" {
    type = string
}

variable "proxmox_api_token_secret" {
    type = string
    sensitive = true
}

These variables are crucial for connecting to Proxmox.

2. VM Configuration

I split the configuration into several parts to keep things clear:

a. Proxmox Connection
proxmox_url = "${var.proxmox_api_url}"
username = "${var.proxmox_api_token_id}"
token = "${var.proxmox_api_token_secret}"
b. Basic Settings
node = "pve"
vm_id = "500"
vm_name = "ubuntu-server-noble"
template_description = "My Ubuntu Server Noble Image"
c. OS Settings
iso_url = "https://releases.ubuntu.com/noble/ubuntu-24.04.2-live-server-amd64.iso"
iso_checksum = "d6dab0c3a657988501b4bd76f1297c053df710e06e0c3aece60dead24f270b4d"
iso_storage_pool = "ISO"
d. Hardware Resources
qemu_agent = true
scsi_controller = "virtio-scsi-pci"

disks {
    disk_size = "20G"
    format = "raw"
    storage_pool = "local"
    type = "virtio"
}

cores = "2"
memory = "2048"
e. Network Setup
network_adapters {
    model = "virtio"
    bridge = "vmbr0"
    firewall = "false"
}

Cloud-init Configuration

In the user-data file, I set up the automatic installation:

autoinstall:
  version: 1
  locale: en_US
  keyboard:
    layout: fr
  ssh:
    install-server: true
    allow-pw: true
    disable_root: true
    ssh_quiet_keygen: true
    allow_public_ssh_keys: true
  packages:
    - qemu-guest-agent
    - sudo
  storage:
    layout:
      name: direct
    swap:
      size: 0
  user-data:
    package_upgrade: false
    timezone: Indian/Reunion
    users:
      - name: admin
        groups: [adm, sudo]
        lock-passwd: false
        sudo: ALL=(ALL) NOPASSWD:ALL
        shell: /bin/bash
        ssh_authorized_keys:
           - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK/b1GlV0l/Os3je6ZWRFvhmyMh/2JJ1PyrbZJAP89DL ubuntu-pkr

Creating the Template: The Moment of Truth!

Checking the Configuration

Before launching the creation, I made sure everything was properly configured:

cd ubuntu-server-noble/
packer validate -var-file='../credentials.pkr.hcl' ./ubuntu-server-noble.pkr.hcl

If you see "The configuration is valid", you're good to go!

Starting the Build

I kicked off the build with this command:

packer build -var-file='../credentials.pkr.hcl' ./ubuntu-server-noble.pkr.hcl

This command will:

  1. Download the Ubuntu ISO
  2. Upload it to my Proxmox server
  3. Start up a new VM
  4. Configure it automatically through SSH
  5. Turn it into a template

The Result

And here's what I got:

My template showing up nicely in Proxmox

Template Specifications

With exactly the specifications I wanted

My Created Template

Now I can create as many VMs as I want from this template, all configured exactly the way I need them. That's the power of automation!

" >

Speed up Proxmox VM deployment with Packer

Speed up Proxmox VM deployment with Packer

Discovering Packer

In my journey to automate infrastructure, I stumbled upon Packer, a fascinating tool developed by HashiCorp. It's a free tool that has allowed me to create prebuilt images for various platforms like AWS, Azure, Digital Ocean, VirtualBox, Proxmox, and many other cloud providers or hypervisors.

What I love most about this command-line tool is that it lets me create custom images with:

  • My favorite applications pre-installed
  • User accounts ready to go
  • SSH keys configured
  • Network settings all set up
  • And tons of other customizations...

I was blown away by how powerful it is for automating infrastructure deployment. Thanks to Packer, I can spin up my testing or development environments in no time. The coolest part? It works on every system: Windows, macOS, and Linux!

How I Got Packer Working with Proxmox

While exploring Packer, I found out it offers two different ways to work with Proxmox:

  • proxmox-iso
  • proxmox-clone
Proxmox Builders


Source: Official Packer Docs

For this guide, I chose to use proxmox-iso because it works perfectly with Proxmox VM templates.

My First Template: A Step-by-Step Experience

What I Wanted to Create

I set out to create a template based on Ubuntu 24.04 (Noble) with these specs:

  • CPU: 2 cores (perfect for my testing needs)
  • RAM: 2048 MB (2GB)
  • Disk: 20GB (plenty to start with)
  • OS: Ubuntu 24.04

Setting Up Packer

Installation

The first cool thing about Packer is that it doesn't need to be on the same machine as Proxmox. To install it, I followed the official documentation.

On my Linux machine, I used these commands:

wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install packer

File Organization

To save you some time, I've created a repository you can clone:

git clone https://github.com/LudovicARHIMAN/Packer-Templates.git

Here's how I organized the files:

.
├── README.md
├── credentials.pkr.hcl
└── ubuntu-server-noble
    ├── files
    │   └── 99-pve.cfg
    ├── http
    │   ├── meta-data
    │   └── user-data
    └── ubuntu-server-noble.pkr.hcl
You won't find the credentials.pkr.hcl file in the repo as it contains sensitive information. I excluded it with .gitignore for security reasons.

Create your own credentials.pkr.hcl file with this template:

proxmox_api_url = "https://0.0.0.0:8006/api2/json"  # Your Proxmox address
proxmox_api_token_id = "GENERATED_API_TOKEN-ID"  # Your token ID
proxmox_api_token_secret = "GENERATED_API_Secret"

Setting Up the API Token in Proxmox

To let Packer talk to Proxmox, we need to create an API token. Here's how I did it:

  1. In the Proxmox web interface, I went to Datacenter > Permissions > API Token
  2. Clicked on Add to create a new token
API Token Creation

Then, I updated my credentials.pkr.hcl file with my information:

proxmox_api_url = "https://pve.reverse9.xyz:8006/api2/json"  # My Proxmox server
proxmox_api_token_id = "root@pam!packer"  # My token ID
proxmox_api_token_secret = "my-secret-token-here"

Understanding the Configuration Files

The Main Template File

The file ubuntu-server-noble/ubuntu-server-noble.pkr.hcl is where the magic happens. Let me walk you through how I configured it:

1. The Essential Variables

variable "proxmox_api_url" {
    type = string
}

variable "proxmox_api_token_id" {
    type = string
}

variable "proxmox_api_token_secret" {
    type = string
    sensitive = true
}

These variables are crucial for connecting to Proxmox.

2. VM Configuration

I split the configuration into several parts to keep things clear:

a. Proxmox Connection
proxmox_url = "${var.proxmox_api_url}"
username = "${var.proxmox_api_token_id}"
token = "${var.proxmox_api_token_secret}"
b. Basic Settings
node = "pve"
vm_id = "500"
vm_name = "ubuntu-server-noble"
template_description = "My Ubuntu Server Noble Image"
c. OS Settings
iso_url = "https://releases.ubuntu.com/noble/ubuntu-24.04.2-live-server-amd64.iso"
iso_checksum = "d6dab0c3a657988501b4bd76f1297c053df710e06e0c3aece60dead24f270b4d"
iso_storage_pool = "ISO"
d. Hardware Resources
qemu_agent = true
scsi_controller = "virtio-scsi-pci"

disks {
    disk_size = "20G"
    format = "raw"
    storage_pool = "local"
    type = "virtio"
}

cores = "2"
memory = "2048"
e. Network Setup
network_adapters {
    model = "virtio"
    bridge = "vmbr0"
    firewall = "false"
}

Cloud-init Configuration

In the user-data file, I set up the automatic installation:

autoinstall:
  version: 1
  locale: en_US
  keyboard:
    layout: fr
  ssh:
    install-server: true
    allow-pw: true
    disable_root: true
    ssh_quiet_keygen: true
    allow_public_ssh_keys: true
  packages:
    - qemu-guest-agent
    - sudo
  storage:
    layout:
      name: direct
    swap:
      size: 0
  user-data:
    package_upgrade: false
    timezone: Indian/Reunion
    users:
      - name: admin
        groups: [adm, sudo]
        lock-passwd: false
        sudo: ALL=(ALL) NOPASSWD:ALL
        shell: /bin/bash
        ssh_authorized_keys:
           - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK/b1GlV0l/Os3je6ZWRFvhmyMh/2JJ1PyrbZJAP89DL ubuntu-pkr

Creating the Template: The Moment of Truth!

Checking the Configuration

Before launching the creation, I made sure everything was properly configured:

cd ubuntu-server-noble/
packer validate -var-file='../credentials.pkr.hcl' ./ubuntu-server-noble.pkr.hcl

If you see "The configuration is valid", you're good to go!

Starting the Build

I kicked off the build with this command:

packer build -var-file='../credentials.pkr.hcl' ./ubuntu-server-noble.pkr.hcl

This command will:

  1. Download the Ubuntu ISO
  2. Upload it to my Proxmox server
  3. Start up a new VM
  4. Configure it automatically through SSH
  5. Turn it into a template

The Result

And here's what I got:

My template showing up nicely in Proxmox

Template Specifications

With exactly the specifications I wanted

My Created Template

Now I can create as many VMs as I want from this template, all configured exactly the way I need them. That's the power of automation!