Créer une image avec Packer : guide pratique pas à pas

Apprenez à créer vos premières images machine avec Packer : structure HCL, builders, provisioners, validation et build. Exemple concret inclus.

Armel NGANDO13 septembre 2026
5 min de lecture33 vues

Comprendre le workflow Packer

Packer automatise la création d’images machine identiques sur plusieurs plateformes (AWS, Azure, GCP, VMware, Docker, etc.). Le processus suit toujours la même logique : un fichier de configuration déclare l’image source, les personnalisations à appliquer, et la plateforme cible. Packer lance une instance temporaire, y applique les modifications, capture l’image, puis détruit l’instance.

Structure d’un template Packer en HCL

Depuis la version 1.7, Packer utilise HCL (HashiCorp Configuration Language) au format .pkr.hcl. Un template minimal contient trois blocs principaux :

  • source : définit le builder (ex: amazon-ebs, azure-arm, docker) et l’image de base
  • build : référence la source et liste les provisioners
  • provisioner : exécute des scripts ou outils de configuration (shell, Ansible, Chef, PowerShell)

Exemple concret : construire une image Docker avec Nginx

Cet exemple utilise le builder docker pour sa simplicité (pas de credentials cloud nécessaires). Créez un répertoire packer-nginx et un fichier nginx.pkr.hcl :

packer {
  required_plugins {
    docker = {
      source  = "github.com/hashicorp/docker"
      version = "~> 1.0"
    }
  }
}

source "docker" "nginx-base" {
  image  = "ubuntu:22.04"
  commit = true
}

build {
  sources = ["source.docker.nginx-base"]

  provisioner "shell" {
    inline = [
      "apt-get update",
      "apt-get install -y nginx"
    ]
  }

  post-processor "docker-tag" {
    repository = "mon-registry/nginx-custom"
    tags       = ["latest", "1.0"]
  }
}

Ce template :

  1. Démarre un conteneur depuis ubuntu:22.04
  2. Installe Nginx via le provisioner shell
  3. Commit le conteneur en image
  4. Tag l’image via le post-processor docker-tag

Initialiser, valider et builder

1. Initialiser le projet

La commande packer init télécharge les plugins déclarés dans le bloc required_plugins :

packer init nginx.pkr.hcl

2. Valider la syntaxe

packer validate vérifie la syntaxe HCL et la cohérence des blocs :

packer validate nginx.pkr.hcl

En cas d’erreur, Packer indique la ligne et le type de problème (variable manquante, bloc inconnu, etc.).

3. Lancer la construction

packer build nginx.pkr.hcl

Sortie typique :

docker.nginx-base: output will be in this color

==> docker.nginx-base: Creating temporary directory for build...
==> docker.nginx-base: Pulling Docker image: ubuntu:22.04
==> docker.nginx-base: Starting docker container...
==> docker.nginx-base: Provisioning with shell script: /tmp/packer-shell123.sh
    docker.nginx-base: Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
    docker.nginx-base: ...
    docker.nginx-base: Setting up nginx (1.18.0-6ubuntu14.4) ...
==> docker.nginx-base: Committing the container
==> docker.nginx-base: Tagging image: mon-registry/nginx-custom:latest
==> docker.nginx-base: Tagging image: mon-registry/nginx-custom:1.0
Build 'docker.nginx-base' finished after 45 seconds.

==> Wait completed after 45 seconds

==> Builds finished. The artifacts of successful builds are:
--> docker.nginx-base: mon-registry/nginx-custom:latest
--> docker.nginx-base: mon-registry/nginx-custom:1.0

Vérifiez l’image :

docker images | grep nginx-custom

Adapter l’exemple pour AWS (AMI)

Remplacez le bloc source par un builder amazon-ebs :

source "amazon-ebs" "ubuntu-nginx" {
  region       = "eu-west-3"
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }
  instance_type = "t3.micro"
  ssh_username  = "ubuntu"
  ami_name      = "nginx-custom-{{timestamp}}"
}

Les provisioners restent identiques. Ajoutez les variables AWS (access_key, secret_key) via variables d’environnement ou fichier .auto.pkrvars.hcl (non versionné).

Bonnes pratiques essentielles

Utiliser des variables pour la réutilisabilité

variable "region" {
  type    = string
  default = "eu-west-3"
}

variable "instance_type" {
  type    = string
  default = "t3.micro"
}

Puis référencez-les : region = var.region.

Gérer les erreurs dans les scripts shell

provisioner "shell" {
  inline = [
    "set -e",
    "apt-get update || (sleep 5 && apt-get update)",
    "apt-get install -y nginx"
  ]
  pause_before = "10s"
}

Séparer les scripts dans des fichiers externes

Pour la maintenabilité, placez la logique d’installation dans scripts/install_nginx.sh et appelez-le :

provisioner "shell" {
  script = "scripts/install_nginx.sh"
}

Chaîner des post-processors

Un post-processor manifest génère un JSON avec les métadonnées du build (AMI ID, digest Docker, etc.), utile en CI/CD :

post-processor "manifest" {
  output = "manifest.json"
  strip_path = true
}

Intégration en pipeline CI/CD

Dans GitLab CI, GitHub Actions ou Jenkins :

  1. packer init
  2. packer validate
  3. packer build (avec variables injectées depuis le vault/secrets manager)
  4. Récupérer l’ID d’image depuis manifest.json pour le déploiement Terraform suivant

Cette approche garantit des images reproductibles, versionnées et auditées. Pour aller plus loin sur l’industrialisation (structure de projet, Makefile, debug, tests), consultez la formation Packer complète sur TeachMeMore.

Débogage courant

  • Timeout SSH : augmentez ssh_timeout ou vérifiez le security group / firewall
  • Image source introuvable : vérifiez les filtres source_ami_filter (owners, name pattern)
  • Provisioner qui échoue silencieusement : ajoutez set -e et des logs explicites
  • Plugin manquant : relancez packer init après modification du bloc required_plugins

Sources

Partager l’article
À propos de l’auteur

Armel NGANDO

Voir ses articles →
Passer de la théorie à la pratique

Construis tes compétences IT avec des parcours structurés.

Formations, labs et projets pour progresser en Systèmes, Cloud et DevOps.

Explorer les formations →

0 commentaire(s)

Laissez un commentaire