Introduction
Packer, outil open-source d'HashiCorp, permet de créer des images machines identiques pour des plateformes multiples comme AWS, Azure ou VirtualBox. En 2026, avec l'essor de l'infrastructure as code (IaC), Packer est indispensable pour standardiser vos environnements de production, réduire les dérives de configuration (drift) et accélérer les déploiements.
Imaginez : au lieu de configurer manuellement une EC2 Ubuntu à chaque fois, vous générez une AMI 'prête-à-l'emploi' avec Nginx, votre app Node.js et les sécurités de base en une commande. Cela élimine les erreurs humaines et assure la reproductibilité.
Ce tutoriel intermédiaire cible les DevOps familiarisés avec AWS. Nous builderons une AMI Ubuntu 22.04 avec provisioner shell pour installer un stack LEMP basique. Résultat : une image immutable, testée et taguée automatiquement. Temps estimé : 20 min. Préparez vos credentials AWS ! (128 mots)
Prérequis
- Packer 1.11+ installé (téléchargeable sur hashicorp/packer)
- Compte AWS avec permissions IAM : AmazonEC2FullAccess, AmazonEBSFullAccess
- AWS CLI v2 configuré (
aws configureavec access key/secret) - Variables d'environnement :
export AWS_ACCESS_KEY_ID=...etAWS_SECRET_ACCESS_KEY=... - Région AWS us-east-1 (modifiable)
- Connaissances de base en HCL et Linux shell
Installation de Packer
#!/bin/bash
# Téléchargement de la dernière version stable (1.11.2 au 2026)
PACKER_VERSION="1.11.2"
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
curl -fsSL "https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_${OS}_${ARCH}.zip" -o packer.zip
unzip -o packer.zip
sudo mv packer /usr/local/bin/
# Vérification
packer version
rm packer.zip packerCe script télécharge, installe et vérifie Packer en un clin d'œil. Utilisez sudo pour l'exécutable global. Piège : Vérifiez l'architecture (amd64/arm64) ; sur M1 Mac, utilisez arm64. Ajoutez export PATH=/usr/local/bin:$PATH si besoin.
Premiers pas : Validation de l'environnement
Avant de coder, testez votre setup AWS. Packer utilise les credentials de l'AWS CLI ou env vars. Créez un dossier projet : mkdir packer-ami && cd packer-ami.
Analogie : Packer est comme un moule à gâteaux : vous définissez la recette (HCL), il produit des images baked prêtes à scaler. Prochaine étape : les variables pour paramétrer région, AMI source, etc. Cela rend le template réutilisable across environnements (dev/prod).
Fichier de variables Packer
aws_region = "us-east-1"
ubuntu_ami = "ami-0c02fb55956c7d316" # Ubuntu 22.04 LTS us-east-1 (vérifiez avec aws ec2 describe-images)
instance_type = "t3.micro"
ssh_username = "ubuntu"
ssh_timeout = "10m"
ami_name = "ubuntu-lemp-${formatdate("YYYYMMDD-HHmm")}" # Timestamp unique
ami_tags = {
Name = "Ubuntu LEMP Packer"
Environment = "production"
ManagedBy = "Packer"
}Ce fichier définit les inputs dynamiques. formatdate assure l'unicité des AMIs. Piège : Mettez à jour ubuntu_ami via AWS Console > EC2 > AMIs publiques. Utilisez des locals pour déduire des valeurs complexes plus tard.
Configuration Packer de base
packer {
required_plugins {
amazon = {
version = ">= 1.1.1"
source = "github.com/hashicorp/amazon"
}
}
required_version = ">= 1.7.0"
}
source "amazon-ebs" "ubuntu" {
access_key = ""
secret_key = ""
region = var.aws_region
ami_name = var.ami_name
instance_type = var.instance_type
source_ami = var.ubuntu_ami
ssh_username = var.ssh_username
ssh_timeout = var.ssh_timeout
tags = var.ami_tags
vpc_filter {
filters = {
"tag:Name" : "Default VPC"
}
}
subnet_filter {
random = true
filters = {
"tag:Name" : "Default subnet"
}
}
}
build {
sources = ["source.amazon-ebs.ubuntu"]
}Template minimal pour builder une AMI custom à partir d'Ubuntu. Le vpc_filter utilise votre Default VPC ; random=true pour subnet. Piège : Sans credentials explicites, Packer lit les env vars AWS. Initiez avec packer init . avant build.
Validation et premier build
Exécutez packer init . pour télécharger le plugin Amazon. Puis packer validate . pour checker la syntaxe HCL. Si OK, lancez le build : cela spin up une EC2 temporaire, snapshot le volume EBS et publie l'AMI.
Astuce : Surveillez les logs pour déboguer (ex: timeouts SSH). L'AMI finale apparaît dans EC2 Console > Images > AMIs owned by me. Temps : 5-10 min.
Build de l'AMI de base
#!/bin/bash
# Initialisation des plugins
packer init .
# Validation HCL
packer validate .
# Build (décommentez -debug pour step-by-step)
packer build -var-file="variables.pkr.hcl" .
# Lister les AMIs créées (optionnel)
aws ec2 describe-images --owners self --filters "Name=name,Values=*ubuntu-lemp*" --query 'Images[*].[ImageId,Name,CreationDate]' --output tableScript complet pour valider/build. -var-file lie les variables. Ajoutez --only=amazon-ebs.ubuntu pour builds spécifiques. Piège : Si VPC non trouvé, créez un ou spécifiez subnet_id hardcodé.
Ajout d'un provisioner Shell
packer {
required_plugins {
amazon = {
version = ">= 1.1.1"
source = "github.com/hashicorp/amazon"
}
}
required_version = ">= 1.7.0"
}
source "amazon-ebs" "ubuntu" {
access_key = ""
secret_key = ""
region = var.aws_region
ami_name = var.ami_name
instance_type = var.instance_type
source_ami = var.ubuntu_ami
ssh_username = var.ssh_username
ssh_timeout = var.ssh_timeout
tags = var.ami_tags
vpc_filter {
filters = {
"tag:Name" : "Default VPC"
}
}
subnet_filter {
random = true
filters = {
"tag:Name" : "Default subnet"
}
}
}
build {
sources = ["source.amazon-ebs.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx mysql-server php8.2-fpm",
"sudo systemctl enable nginx mysql",
"echo '<h1>LEMP Packer AMI OK</h1>' | sudo tee /var/www/html/index.html",
"sudo mysql_secure_installation <<EOF\nY\ny\nroot\nY\nY\nY\nY\nEOF"
]
timeout = "10m"
}
}Provisioner shell installe LEMP (Linux, Nginx, MySQL, PHP) post-boot. inline exécute des commandes séquentielles. Piège : mysql_secure_installation est interactif ; utilisez heredoc pour automatiser. Timeout prévient les hangs.
Build avec provisioner
#!/bin/bash
packer init .
packer validate .
# Build avec force pour re-créer (supprime anciennes AMIs si besoin)
packer build -force -var-file="variables.pkr.hcl" .
# Test : Lancer une instance depuis l'AMI et curl localhost-force recrée l'AMI sans conflit de nom. Post-build, testez en lançant une EC2. Piège : Coûts AWS ~0.02$/build ; nettoyez avec aws ec2 deregister-image et delete snapshots.
Bonnes pratiques
- Utilisez des variables et locals : Centralisez creds/secrets dans
auto.pkrvars.hcl(gitignore !) etlocals { timestamp = formatdate... }pour dynamisme. - Multi-builders : Ajoutez
source "virtualbox-iso" {}pour local testing avant cloud. - Provisioners idempotents : Préférez Ansible/Chef à shell brut pour rejouabilité.
- Post-processors :
post-processor "manifest" {}pour JSON d'output ;compresspour packer l'AMI. - CI/CD : Intégrez à GitHub Actions/Terraform Cloud pour builds automatisés on-push.
Erreurs courantes à éviter
- Timeout SSH : Augmentez
ssh_timeoutà 20m ; vérifiez Security Group (SSH 22 ouvert). - AMI source obsolète : Query AWS :
aws ec2 describe-images --filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04*' --owners 099720109477. - Permissions IAM insuffisantes : Attachez policy
EC2InstanceProfileForImageBuilder. - Dérive VPC : Hardcodez
subnet_idou créez dedicated VPC pour Packer.
Pour aller plus loin
Maîtrisez les builders avancés (Azure, GCP) et builders customs. Consultez la doc officielle Packer. Intégrez avec Terraform via data.aws_ami. Découvrez nos formations DevOps Learni pour Packer + Terraform en prod.