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.

📋 Au programme
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
local:iso/).secret-vars-proxmox.pkr.hcl créé et exclu du Gitmachine-id bien réinitialisé dans le script de post-provisioningErreurs 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
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é.