Skip to content
Learni
Voir tous les tutoriels
DevOps

Comment créer des images AMIs avec Packer en 2026

Read in English

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 configure avec access key/secret)
  • Variables d'environnement : export AWS_ACCESS_KEY_ID=... et AWS_SECRET_ACCESS_KEY=...
  • Région AWS us-east-1 (modifiable)
  • Connaissances de base en HCL et Linux shell

Installation de Packer

install-packer.sh
#!/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 packer

Ce 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

variables.pkr.hcl
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

ubuntu.pkr.hcl
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

build-base.sh
#!/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 table

Script 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

ubuntu.pkr.hcl
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

build-lemp.sh
#!/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 !) et locals { 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 ; compress pour 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_id ou 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.