Packer et cloud-init interviennent tous les deux dans un pipeline d’image golden, et pourtant confondre leur rôle respectif casse silencieusement ce pipeline : un script de provisioning placé au mauvais endroit (dans le mauvais outil, au mauvais moment) s’exécute soit trop tôt, soit jamais, soit à chaque démarrage d’instance plutôt qu’une seule fois.
Packer : construire une image, une seule fois, jamais en production
Packer démarre une machine temporaire (une VM, un conteneur), y exécute les scripts de provisioning demandés, capture le résultat sous forme d’image (AMI, image disque, image de conteneur), puis détruit la machine temporaire : cette machine n’existe jamais en production, uniquement le temps de la construction de l’image.
# packer.pkr.hcl : provisionne une machine temporaire,
# jamais utilisée directement en production
build {
sources = ["source.amazon-ebs.example"]
provisioner "shell" {
script = "install-nginx.sh"
}
}
Tout ce qui doit être identique sur chaque instance dérivée de cette image (paquets installés, configuration système commune) appartient à cette étape, exécutée une seule fois par version d’image, jamais relancée au démarrage d’une instance individuelle.
cloud-init : configurer chaque instance, à son premier démarrage
cloud-init, déjà documenté pour le piège du clonage de VM, intervient au moment où une instance individuelle démarre réellement à partir de l’image construite par Packer : il configure ce qui doit varier d’une instance à l’autre (nom d’hôte, clés SSH host propres à cette instance, injection de secrets ou de configuration spécifique via user-data).
# user-data : exécuté au premier démarrage
# de CETTE instance précise, jamais lors du build Packer
#cloud-config
hostname: web-01
packages:
- htop
Le piège : mélanger les deux moments
Un script d’installation de paquet placé dans user-data plutôt que dans un provisioner Packer s’exécute à chaque nouveau démarrage d’instance, ralentissant inutilement chaque déploiement d’une opération qui aurait dû être figée une seule fois dans l’image. À l’inverse, une configuration propre à l’instance (un nom d’hôte, une clé d’API spécifique à l’environnement) figée dans l’image par Packer plutôt que gérée par cloud-init rend cette image inutilisable pour plus d’une instance à la fois, brisant l’intérêt même d’une image réutilisable.
Le découpage qui fonctionne
Packer prend en charge tout ce qui est commun à toutes les instances futures (le logiciel installé, les durcissements système), produisant une image versionnée et immuable. cloud-init prend en charge tout ce qui distingue une instance individuelle des autres au démarrage, à partir de cette même image. Le critère de décision est simple : si la même valeur doit apparaître sur chaque instance sans exception, elle appartient à Packer ; si elle varie d’une instance à l’autre, elle appartient à cloud-init.
À retenir
Packer construit une image une seule fois, sur une machine temporaire ensuite détruite, jamais présente en production : tout ce qui doit être identique sur chaque instance dérivée appartient à cette étape. cloud-init configure chaque instance individuellement à son premier démarrage réel, à partir de cette image déjà construite : tout ce qui varie d’une instance à l’autre lui appartient. Mélanger les deux moments casse silencieusement le pipeline, soit en ralentissant chaque démarrage d’une opération qui aurait dû être figée une fois pour toutes, soit en produisant une image non réutilisable faute d’avoir laissé la configuration spécifique à cloud-init.