Packer Proxmox : créer des templates Debian automatiques et reproductibles

Infrastructure as Code · Proxmox · HashiCorp

Créer des templates Proxmox à la main, c’est chronophage et source d’incohérences entre environnements. Avec Packer, j’automatise entièrement la génération d’images Debian standardisées, reproductibles et prêtes à être clonées en quelques secondes. Voici ma méthode, basée sur un projet que j’utilise en production chez Linux-Man.

Packer Proxmox : workflow de création automatique de templates Debian avec fichier HCL et script de provisioning
Workflow Packer : du fichier HCL au template Proxmox prêt à cloner.

Pourquoi automatiser la création de templates Proxmox avec Packer ?

Si tu gères plusieurs serveurs ou si tu dois provisionner des VMs fréquemment, cette approche va te faire gagner un temps considérable — et surtout éliminer les erreurs liées aux configurations manuelles disparates.

Sans automatisation, créer un template Proxmox propre demande de :

  • Télécharger et monter l’ISO manuellement
  • Installer le système via l’interface Proxmox
  • Appliquer les configurations de base (SSH, sudo, machine-id…)
  • Convertir la VM en template
  • Recommencer à chaque nouvelle version de Debian

💡

Résultat avec Packer

Un seul fichier .hcl versionné dans Git, exécutable en une commande. Des templates identiques à chaque build, traçables et auditables.

Architecture du projet

Mon projet packer-deploy-images couvre à la fois Proxmox et VirtualBox. Voici la structure principale :

packer-deploy-images/
├── template-proxmox.pkr.hcl        # Template principal Proxmox
├── vars_debian12_proxmox.pkrvars.hcl  # Variables Debian 12
├── plugins.pkr.hcl                 # Déclaration des plugins
├── http/                           # Preseed Debian (réponses auto-install)
├── script_start.sh                 # Script de post-provisioning
└── id_ecdsa.pub                    # Clé SSH à déployer

Prérequis

  • Un nœud Proxmox VE fonctionnel (accès API activé)
  • Packer installé sur ta machine de build (packer version ≥ 1.9)
  • Le plugin Proxmox Packer (hashicorp/proxmox ~> 1)
  • Un ISO Debian 12 disponible dans le stockage Proxmox
  • Un compte Proxmox avec les droits de création VM

Installation de Packer et du plugin

# Installation Packer (Debian/Ubuntu)
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [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

# Initialisation du projet (télécharge les plugins déclarés)
packer init .

Le fichier plugins.pkr.hcl déclare les plugins nécessaires :

packer {
    required_plugins {
        proxmox = {
            source  = "github.com/hashicorp/proxmox"
            version = "~> 1"
        }
    }
}

Configuration des variables Proxmox

⚠️

Ne jamais committer les secrets

Le fichier .secret-vars-proxmox.pkr.hcl doit être dans .gitignore. En CI/CD, utilise les variables d’environnement GitLab (PKR_VAR_password) — jamais de fichier de secrets dans le dépôt.

Je stocke les paramètres sensibles dans un fichier exclu du dépôt Git :

# .secret-vars-proxmox.pkr.hcl (ne jamais committer ce fichier)
proxmox_url = "https://proxmox.ton-domaine.com:8006/api2/json"
node        = "pve"
username    = "root@pam"
password    = "CHANGE_ME"

Les variables non sensibles sont dans le fichier de vars Debian 12 :

# vars_debian12_proxmox.pkrvars.hcl
boot_command = [
  "<esc><wait>auto console-keymaps-at/keymap=fr debconf/frontend=noninteractive fb=false url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg<enter>"
]
cores                    = "1"
sockets                  = "1"
disk_size                = "30G"
storage_pool             = "local-lvm"
storage_pool_type        = "scsi"
insecure_skip_tls_verify = true
format                   = "qcow2"
iso_checksum             = "sha256:64d727dd5785ae5fcfd3ae8ffbede5f40cca96f1580aaa2820e8b99dae989d94"
iso_file                 = "local:iso/debian-12.4.0-amd64-netinst.iso"
iso_storage_pool         = "local"
memory                   = 1024
ssh_timeout              = "30m"
ssh_username             = "vagrant"
template_name            = "debian-12-lvm"
template_description     = "Debian 12 LVM, generated by Packer"
tags                     = "debian-12;template;lvm"
network_bridge           = "vmbr0"
network_model            = "virtio"

Structure du template Proxmox

Le fichier template-proxmox.pkr.hcl définit la source et les provisioners. Voici les éléments clés :

source "proxmox-iso" "debian" {
    proxmox_url              = var.proxmox_url
    node                     = var.node
    username                 = var.username
    password                 = var.password
    insecure_skip_tls_verify = var.insecure_skip_tls_verify

    iso_file         = var.iso_file
    iso_checksum     = var.iso_checksum
    iso_storage_pool = var.iso_storage_pool

    disks {
        disk_size    = var.disk_size
        storage_pool = var.storage_pool
        type         = var.storage_pool_type
    }

    efi_config {
        efi_storage_pool  = var.storage_pool
        efi_type          = "4m"
        pre_enrolled_keys = true
    }

    network_adapters {
        model    = var.network_model
        bridge   = var.network_bridge
        firewall = var.network_firewall
    }

    http_directory       = var.http_directory
    boot_command         = var.boot_command
    boot_wait            = var.boot_wait
    ssh_username         = var.ssh_username
    ssh_password         = var.ssh_password
    ssh_timeout          = var.ssh_timeout
    template_name        = var.template_name
    template_description = "${var.template_description} - ${local.packer_timestamp}"
    unmount_iso          = true
    tags                 = var.tags
}

build {
    sources = ["source.proxmox-iso.debian"]

    provisioner "file" {
        destination = var.provision_file_destination
        source      = var.provision_file_source
    }

    provisioner "shell" {
        script          = var.provision_shell_script
        execute_command = var.provision_shell_execute_command
    }
}

Post-provisioning : ce que fait le script de démarrage

Le script script_start.sh s’exécute en fin de build pour préparer l’image de base :

#!/bin/sh
# Déployer la clé SSH
mkdir -p /root/.ssh /home/vagrant/.ssh
mv /tmp/id_ecdsa.pub /root/.ssh/
cp /root/.ssh/id_ecdsa.pub /home/vagrant/.ssh/
chmod 400 /root/.ssh/id_ecdsa.pub /home/vagrant/.ssh/id_ecdsa.pub
cat /root/.ssh/id_ecdsa.pub >> /root/.ssh/authorized_keys
cat /home/vagrant/.ssh/id_ecdsa.pub >> /home/vagrant/.ssh/authorized_keys
chmod 400 /root/.ssh/authorized_keys /home/vagrant/.ssh/authorized_keys

# Mise à jour système
apt update -y

# Réinitialiser le machine-id (indispensable pour les clones)
truncate -s 0 /etc/machine-id
rm /var/lib/dbus/machine-id
ln -s /etc/machine-id /var/lib/dbus/machine-id

# Accès sudo sans mot de passe pour vagrant
echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

🔴

Point critique : machine-id

La réinitialisation du machine-id est indispensable. Sans ça, toutes les VMs clonées depuis ce template auront le même identifiant réseau — source de conflits DHCP et d’adresses IP en doublon.

Lancer le build

# Valider la syntaxe avant de lancer
packer validate \
  -var-file=vars_debian12_proxmox.pkrvars.hcl \
  -var-file=.secret-vars-proxmox.pkr.hcl \
  template-proxmox.pkr.hcl

# Lancer le build
packer build \
  -var-file=vars_debian12_proxmox.pkrvars.hcl \
  -var-file=.secret-vars-proxmox.pkr.hcl \
  template-proxmox.pkr.hcl

Le build prend entre 10 et 20 minutes selon la connexion (téléchargement ISO + installation). À la fin, le template apparaît directement dans l’interface Proxmox, prêt à être cloné.

✅ Checklist avant le premier build

ISO Debian 12 présent dans le stockage Proxmox (local:iso/)
Fichier .secret-vars-proxmox.pkr.hcl créé et exclu du Git
Checksum ISO vérifié (SHA256)
Port HTTP accessible depuis Proxmox (Packer sert le preseed via HTTP)
machine-id bien réinitialisé dans le script de post-provisioning
Tags définis pour retrouver le template facilement dans Proxmox

Erreurs fréquentes

⏱ Timeout SSH

Packer ne parvient pas à se connecter en SSH à la VM en cours d’installation. Cause la plus fréquente : le preseed (http/preseed.cfg) n’est pas accessible depuis la VM Proxmox. Vérifie que le firewall de ta machine de build autorise les connexions entrantes sur le port HTTP éphémère.

🔒 TLS verify error

Si tu utilises un certificat auto-signé sur Proxmox, positionne insecure_skip_tls_verify = true dans tes vars.

🆔 Machine-id identique après clonage

Le truncate -s 0 /etc/machine-id n’a pas été exécuté. Toutes les VMs clonées auront le même machine-id jusqu’à leur premier reboot.

💿 ISO introuvable

Vérifie le chemin exact de l’ISO dans Proxmox (local:iso/nom-exact-du-fichier.iso) et mets à jour la variable iso_file en conséquence.

Cas d’usage concrets

🏢

VMs clients standardisées

Chaque client part d’un template identique, avec les mêmes configs de base (SSH, sudo, machine-id propre).

🧪

Test des rôles Ansible

Clone rapide d’une VM propre depuis le template pour valider un playbook avant déploiement.

📦

Multi-versions Debian

Templates Debian 11, 12 et 13 régénérés à chaque mise à jour majeure.

Provisioning rapide

Cloner un template : 30 secondes. Installation complète : 15–20 minutes. Le choix est vite fait.

Aller plus loin : intégration CI/CD

Une fois cette base posée, il est simple d’intégrer le build Packer dans un pipeline GitLab CI pour regénérer automatiquement les templates à chaque mise à jour de l’ISO ou du script de provisioning :

# .gitlab-ci.yml (extrait)
build-debian12-template:
  stage: build
  script:
    - packer init .
    - packer validate -var-file=vars_debian12_proxmox.pkrvars.hcl template-proxmox.pkr.hcl
    - packer build -var-file=vars_debian12_proxmox.pkrvars.hcl template-proxmox.pkr.hcl
  only:
    - main

Bonne pratique CI/CD

Les variables sensibles (proxmox_url, password) sont injectées via les variables CI/CD GitLab sous forme de PKR_VAR_* — jamais stockées dans le dépôt.

FAQ

Quelle différence entre Packer proxmox-iso et proxmox-clone ?
Le builder proxmox-iso crée un template depuis zéro à partir d’un ISO — c’est le point de départ. Le builder proxmox-clone clone un template existant et applique des modifications dessus. Pour créer le template de base, proxmox-iso est la bonne option.
Peut-on utiliser cloud-init avec ce template ?
Oui. Il suffit d’installer cloud-init dans le script de post-provisioning et d’activer le support cloud-init dans Proxmox (ajout d’un lecteur cloud-init à la VM). Tu peux ensuite personnaliser chaque clone via cloud-init sans modifier le template.
Comment mettre à jour un template existant ?
Il n’y a pas de mise à jour incrémentale d’un template Proxmox. La méthode recommandée avec Packer : regénérer le template complet (nouveau build), puis supprimer l’ancien après validation. Le timestamp est automatiquement inclus dans la description du template pour tracer les versions.
Le fichier .secret-vars est-il vraiment sécurisé ?
Il l’est tant qu’il est dans .gitignore et jamais commité. En CI/CD, n’utilise jamais de fichier de secrets : injecte les variables sensibles via les variables d’environnement de ton pipeline (PKR_VAR_password, PKR_VAR_proxmox_url…).
Packer fonctionne-t-il avec Proxmox VE 8 ?
Oui, le plugin hashicorp/proxmox ~> 1 est compatible avec Proxmox VE 7 et 8. Pense à vérifier les notes de version du plugin si tu utilises des fonctionnalités récentes de l’API Proxmox.
Combien de temps prend un build ?
Entre 10 et 25 minutes, selon la connexion réseau (téléchargement ISO), les ressources du nœud Proxmox et la complexité du script de post-provisioning. Les builds suivants (si l’ISO est déjà en cache local) prennent 8 à 15 minutes.

Conclusion

Packer transforme la gestion des templates Proxmox en processus fiable, versionné et reproductible. Un seul fichier HCL, une commande — et ton infrastructure démarre toujours du même point propre. C’est la base d’une infrastructure as code cohérente, surtout quand on multiplie les environnements clients ou les projets.

Tu veux aller plus loin ?

Je peux t’accompagner sur la mise en place d’un pipeline complet de provisioning Proxmox — de la création des templates à leur déploiement automatisé.

Contacte-moi →

Laisser un commentaire