10. Cloud-Init — préparer une VM pour le déploiement automatisé
10.1 Le problème que cloud-init résout
Installer Debian manuellement depuis un ISO prend entre 10 et 20 minutes, et le résultat est une VM unique qu'on ne peut pas reproduire à l'identique. Dans un environnement où l'on déploie régulièrement des VMs (développement, tests, staging), ce processus devient un goulot d'étranglement.
Cloud-init est un outil de personnalisation au premier démarrage, adopté comme standard par la quasi-totalité des images cloud (Debian cloud, Ubuntu Server, Rocky Linux, AlmaLinux). Au lieu d'installer un OS depuis une ISO, vous partez d'une image déjà installée et configurée, et cloud-init injecte vos paramètres — hostname, utilisateur, clé SSH, réseau — lors du premier boot.
Proxmox intègre cloud-init nativement : il génère un disque virtuel spécial (datasource nocloud) qui est attaché à la VM et lu par cloud-init au démarrage.
10.2 Préparer une image cloud-init
Le cours et l'atelier n'utilisent pas les mêmes numéros. Dans les exemples du cours, le template porte le numéro 9000, et les clones 101 et 102 sont des clones liés.
Dans les ateliers, votre template est la VM 100, et vos VM 101 et 102 en sont des clones intégraux. Suivez les numéros de l'atelier.
La méthode complète part d'une VM Debian installée manuellement, puis la transforme en image générique prête à être clonée.
Comprendre ce que cloud-init fait, avant de le préparer. Une image de template est volontairement anonyme : pas de nom d'hôte, pas d'utilisateur, pas de clé, pas d'adresse.
Si on clonait une VM déjà configurée, toutes les copies partageraient la même identité : même hostname, même clé SSH d'hôte, parfois même machine-id. Cela casse la résolution et la sécurité. Cloud-init résout cela en injectant l'identité au premier démarrage, à partir des paramètres passés par Proxmox.
D'où une étape que les débutants oublient et qui explique la moitié des templates ratés : le nettoyage avant conversion en template. Il faut effacer de la VM tout ce qui la rend unique — machine-id, clés SSH d'hôte, journaux, baux DHCP — sans quoi les clones en hériteront. C'est l'objet de la commande cloud-init clean et de la purge du machine-id, détaillées dans les étapes qui suivent.
La règle à retenir : un template se prépare une fois, se nettoie, puis ne se redémarre plus jamais tel quel. Le rallumer régénérerait le machine-id qu'on vient d'effacer, et le template redeviendrait pollué.
Étape 1 — Dans la VM : installer les prérequis
Dans la VM (sa Console, ou en SSH) :
# Depuis l'intérieur de la VM Debian
apt update # la liste des paquets
apt install -y cloud-init qemu-guest-agent # cloud-init et l'agent QEMU
# Rien à activer pour l'agent : son service démarre seul dès que la VM possède
# le port de l'agent (option --agent enabled=1, posée sur le template)
# Nettoyer avant de créer le template
cloud-init clean --logs # supprimer les données d'init précédentes
truncate -s 0 /etc/machine-id # réinitialiser l'ID machine (chaque clone aura le sien)
rm -f /var/lib/dbus/machine-id # retirer la copie D-Bus de l'identifiant
ln -s /etc/machine-id /var/lib/dbus/machine-id # D-Bus lira le même identifiant que le système
rm -f /etc/ssh/ssh_host_* # supprimer les clés SSH hôte (régénérées au premier boot)
apt clean # vider le cache des paquets téléchargés
poweroff # éteindre la VM avant d'en faire un template
Résultat attendu — la VM s'éteint proprement :
...
[ OK ] Stopped Session 1 of User root.
[ OK ] Reached target System Shutdown.
[ OK ] Reached target Late Shutdown Services.
Unmounting /boot...
[ OK ] Unmounted /boot.
Stopping D-Bus System Message Bus...
[ OK ] Stopped D-Bus System Message Bus.
[ OK ] Reached target Unmount All Filesystems.
Connection to 10.44.1.55 closed.
La connexion SSH se ferme automatiquement à l'extinction de la VM. Dans l'interface Proxmox, la VM passe en statut stopped — c'est le moment de configurer cloud-init depuis l'hôte.
Étape 2 — Sur l'hôte Proxmox : configurer cloud-init
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Ajouter le lecteur cloud-init (génère l'image datasource nocloud)
# Il prend la place du lecteur CD de l'installation, devenu inutile
qm set 100 --ide2 local-lvm:cloudinit
# Configurer le hostname, l'utilisateur et la clé SSH via cloud-init
qm set 100 --ciuser devops
qm set 100 --cipassword 'dawan' # mot de passe de cet utilisateur
qm set 100 --sshkeys ~/.ssh/authorized_keys # clé SSH publique autorisée
# Adresse FIXE, conformement a la regle de l infrastructure de lab :
# chaque stagiaire dispose d un reseau NATe en 10.44.1.x, et toute
# ressource creee y porte une adresse fixe. Prenez celle de votre plan
# d adressage plutot que celle-ci telle quelle.
qm set 100 --ipconfig0 ip=10.44.1.55/24,gw=10.44.1.1
# Le mode DHCP existe (valeur "dhcp" pour ipconfig0), mais il est ecarte ici :
# clonees du meme template obtiendraient un bail imprevisible, et le plan
# d adressage du lab exige une adresse fixe sur chaque ressource creee.
# Régénérer l'image cloud-init après modification
qm cloudinit update 100
# Démarrer la VM — cloud-init applique la configuration au premier boot
qm start 100
Résultat attendu au premier démarrage — dans la VM 101 du lab, depuis le nœud, par l'agent invité (qm guest exec 101 -- cloud-init status, puis qm guest exec 101 -- tail -n 1 /var/log/cloud-init-output.log) :
status: done
Cloud-init v. 25.1.4 finished at Tue, 29 Sep 2026 11:53:13 +0000. Datasource DataSourceNoCloud [seed=/dev/sr0]. Up 10.96 seconds
status: done : cloud-init a terminé tous ses modules. DataSourceNoCloud [seed=/dev/sr0] : la configuration venait du lecteur CD que Proxmox génère (la ligne generating cloud-init ISO au qm start).
L'utilisateur devops est créé avec la clé SSH injectée, le hostname est appliqué, et le réseau configuré selon ipconfig0. La VM est immédiatement accessible en SSH sans passer par la console.
Étape 3 — Dans l'interface graphique :
Proxmox expose un onglet dédié cloud-init pour chaque VM : VM → Cloud-Init.
| Champ | Valeur |
|---|---|
| User | devops |
| Password | dawan |
| SSH public key | coller la clé publique |
| IP Config (net0) | ip=10.44.1.55/24,gw=10.44.1.1 — adresse fixe |
| DNS domain | (facultatif) |
Après modification, cliquez Regenerate Image pour appliquer les changements avant le prochain démarrage.
- 📖 Documentation Proxmox — Cloud Init Support
- 📖 Documentation cloud-init
- 🎥 Techno Tim — la procédure complète, de l'image au template cloud-init (vidéo en anglais)
10.3 Utiliser des images cloud préconstruites
Les distributions majeures publient des images cloud prêtes à l'emploi, déjà équipées de cloud-init. C'est la méthode la plus rapide pour créer un template, et en pratique celle qu'on utilise presque toujours. La préparation manuelle de la section précédente sert surtout à comprendre ce que l'image cloud fait déjà pour vous.
L'intérêt dépasse la rapidité. Ces images sont construites et testées par la distribution elle-même : nettoyées, minimales, sans machine-id figé, avec cloud-init déjà configuré.
On évite ainsi toutes les erreurs de préparation vues plus haut. C'est aussi ce qui garantit la reproductibilité — l'image debian-13-generic est identique pour tout le monde, à l'octet près, vérifiable par son empreinte.
Le format .qcow2 de ces images appelle un réflexe : leur taille de disque est minuscule (souvent 2 à 3 Go), car elles sont provisionnées au plus juste. Après import, il faut donc agrandir le disque avec qm disk resize avant de créer des VMs utilisables — sans quoi le clone démarre avec un disque presque plein. C'est l'oubli le plus fréquent avec les images cloud.
Un dernier point : la ligne qm set ... --ide2 ...cloudinit de la procédure n'ajoute pas un disque de données mais le lecteur cloud-init. C'est un petit disque virtuel qui transporte l'identité (nom, IP, clé) jusqu'à la VM au premier démarrage. Sans lui, cloud-init n'a aucune source de configuration à lire, et le clone démarre anonyme.
Dans le Shell du nœud (interface web → votre nœud → Shell) :
# Télécharger l'image cloud Debian 13 (Trixie)
wget -P /tmp/ https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2
# Créer une VM squelette (sans disque) ; processeur compatible avec tout le cluster
qm create 9000 --name debian-13-cloud --memory 2048 --cores 2 \
--net0 virtio,bridge=vmbr0 --ostype l26 --agent enabled=1 --cpu x86-64-v2-AES
# Importer l'image cloud : elle arrive comme disque non attaché (unused0)
qm disk import 9000 /tmp/debian-13-generic-amd64.qcow2 local-lvm
# Attacher le disque importé et configurer le boot
qm set 9000 --scsi0 local-lvm:vm-9000-disk-0,discard=on,ssd=1
qm set 9000 --boot order=scsi0 # démarrer sur ce disque
# Ajouter le disque cloud-init
qm set 9000 --ide2 local-lvm:cloudinit
qm set 9000 --serial0 socket --vga serial0 # console série, utilisée par les images cloud
# Agrandir le disque à 20 Go
qm disk resize 9000 scsi0 20G
# Convertir en template
qm template 9000
Résultat attendu — l'import, puis la conversion en template :
importing disk '/tmp/debian-13-generic-amd64.qcow2' to VM 9000 ...
Logical volume "vm-9000-disk-0" created.
transferred 3.0 GiB of 3.0 GiB (100.00%)
unused0: successfully imported disk 'local-lvm:vm-9000-disk-0'
...
Renamed "vm-9000-disk-0" to "base-9000-disk-0" in volume group "pve"
Logical volume pve/base-9000-disk-0 changed.
Deux détails de cette sortie éclairent la suite. L'import dépose le disque en unused0 : il existe, mais n'est branché nulle part, d'où la commande qm set 9000 --scsi0 … qui l'attache.
Et la conversion renomme le disque de vm-9000-disk-0 en base-9000-disk-0, en lecture seule. C'est le signe qu'il est devenu une base, que les clones liés vont partager sans jamais la modifier. La VM 9000 passe en mode template dans l'interface — son icône change et elle n'est plus démarrable directement.
- 📖 Images cloud officielles de Debian — pour Debian 13, le dossier trixie/latest contient
debian-13-generic-amd64.qcow2et son fichier d'empreintesSHA512SUMS - 📖 Images cloud officielles d'Ubuntu
- 🎥 Jim's Garage — cloner des VM avec cloud-init et Terraform (vidéo en anglais) : coupler le template à Terraform pour automatiser le provisionnement, une pratique courante en environnement DevOps.
Proxmox VE — TSSR