Table des matières :
- Terraform + conteneurs : le découplage qui évite les environnements « floconneux »
- Terraform côté infra : state, modules, providers, et gestion des secrets (sans se mentir)
- Conteneuriser proprement : images OCI reproductibles, build déterministe, et limites spécifiques PrestaShop
- Où s’arrête Terraform et où commence l’orchestration : Compose, Kubernetes, et l’anti-pattern du « tout dans HCL »
- Déploiements reproductibles : pipeline, registries, SBOM, et rollback réel (pas théorique)
- Observabilité et exploitation : drift, métriques, logs, et runbooks qui tiennent en prod
- Checklist opérationnelle (sans “best practices” creuses) pour une infra PrestaShop IaC + conteneurs
Terraform n’est pas “le déploiement”, et les conteneurs ne sont pas “l’infra”. Les deux se complètent si (et seulement si) vous acceptez une séparation nette des responsabilités : Terraform décrit des ressources (réseau, compute, LB, DNS, stockage, IAM), tandis que les conteneurs (OCI/Docker) encapsulent des artefacts applicatifs (runtime, dépendances, config) destinés à être exécutés de façon reproductible.
Pour éviter les confusions en équipe (et les “on a tout mis dans Terraform”), gardez ce repère simple :
| Sujet | Source de vérité | Outil typique | Objectif |
|---|---|---|---|
| Réseau, IAM, LB, DNS, stockage, cluster | Git + state Terraform | Terraform | Convergence & drift detection |
| Artefact applicatif | Registry (digest) | CI (build) | Reproductibilité |
| Déploiement & rollout | Git (manifests/Helm) | Orchestrateur / GitOps | Self-healing, scaling, rollback |
| Secrets runtime | Secret manager | Vault / cloud secret manager | Rotation, moindre privilège |
Terraform + conteneurs : le découplage qui évite les environnements « floconneux »
L’Infrastructure as Code (IaC) n’est pas un slogan, c’est une contrainte de reproductibilité. La définition la plus claire reste celle-ci : « Infrastructure as code (IaC) is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools. » (Wikipedia — Infrastructure as code). Ça implique versioning, revue de code, et capacité à recréer un environnement sans “clique-droit dans la console”.
Terraform se situe exactement à cet endroit. HashiCorp résume le périmètre sans ambiguïté : « Terraform is an infrastructure as code tool that lets you build, change, and version infrastructure safely and efficiently. » (HashiCorp – Terraform Intro). Si vous utilisez Terraform pour “installer PrestaShop” ou “déployer du code” via des scripts remote-exec, vous sortez du cadre et vous vous exposez à des diffs non déterministes, à des timeouts, et à des replays dangereux.
Un bon test (très opérationnel) pour savoir si vous êtes en train de créer un “flocon” : si l’état final dépend de l’ordre d’exécution ou d’un accès réseau éphémère, vous n’êtes plus dans une convergence IaC mais dans du scripting fragile. Exemple typique : “je crée une VM avec Terraform, puis je SSH dedans et je lance un script d’install”. À la première réexécution partielle, vous obtenez un serveur dans un état intermédiaire (paquets partiellement mis à jour, config modifiée à la main, versions divergentes).
Les conteneurs, eux, résolvent un autre problème : figer l’artefact applicatif (image OCI) et rendre l’exécution stable entre un laptop et un runner CI. Le point clé, c’est de ne pas confondre exécution (Docker/Containerd/Kubernetes) et provisionnement (Terraform). Quand vous mélangez les deux, vous créez un système où la “source de vérité” est éclatée entre l’état Terraform, des scripts ad hoc, et des volumes persistants qui survivent à tout.
Mini-scénario (réaliste en e-commerce) : vous avez un PrestaShop en staging sur une petite infra, “proche de prod”. Un admin ouvre “temporairement” un port SSH sur le security group, un autre modifie une règle de redirect TLS côté LB, et votre prochain terraform apply “corrige” ces changements… mais pas dans le bon sens, parce que les modifications n’étaient ni revues ni documentées. Résultat : incident de disponibilité + effet de bord SEO (mauvaise canonicalisation, HTTP/HTTPS incohérent). Le découplage Terraform (infra) / conteneurs (app) réduit précisément ce type d’accidents.
Terraform côté infra : state, modules, providers, et gestion des secrets (sans se mentir)
La pièce maîtresse de Terraform, c’est le state. Sans état fiable, pas de drift detection, pas de plan reproductible. En 2026, le minimum syndical pour un projet sérieux : backend distant (S3 + DynamoDB lock, GCS, Azure Blob, Terraform Cloud, etc.) + chiffrement at-rest + verrouillage de concurrence. Garder terraform.tfstate en local finit toujours en incident (mauvais apply, divergence entre membres d’équipe, secret leak). Sur un site e-commerce, l’impact se mesure vite : downtime réseau, suppression d’instances, ou rotation involontaire d’IP publiques qui casse DNS/TLS.
Deux points souvent sous-estimés :
- Le contrôle d’accès au state est aussi critique que l’accès au compte cloud. Un acteur qui lit le state peut récupérer des endpoints internes, des IDs, parfois des secrets, et cartographier votre infra.
- Le “qui a fait quoi” : activez l’audit (logs d’accès au bucket/state, traces Terraform Cloud, ou équivalent), parce qu’en incident, vous voulez relier un changement d’infra à un auteur et un commit.
Le deuxième pilier : modules et interfaces stables. Un module Terraform n’est pas un dossier “utilitaire”, c’est un contrat. Exposez des variables minimales (CIDR, taille, tags, policy IAM) et des outputs exploitables (IDs, endpoints). Versionnez vos modules (tag Git) et évitez de “pinner” une branche. Exemple simple (structure) :
infra/
envs/
prod/
main.tf
versions.tf
backend.tf
staging/
modules/
network/
compute/
database/
Si vous travaillez avec plusieurs régions ou plusieurs datacenters (cas fréquent en France/UE pour la latence et la résidence des données), évitez le “copier-coller” d’environnements. Préférez :
- une convention de variables claire (
region,environment,owner,cost_center) ; - un tagging strict (utile pour facturation et gouvernance) ;
- des modules capables d’exprimer des différences réelles (par exemple : WAF activé seulement en prod, tailles différentes, rétention logs différente).
Côté providers et versions, la discipline qui évite les upgrades implicites :
- pinner Terraform et les providers dans
versions.tf; - committer le fichier de verrouillage
.terraform.lock.hcl(sinon deux machines peuvent résoudre des versions de providers différentes) ; - traiter les upgrades comme un changement applicatif : plan en CI, revue, fenêtre de déploiement.
Enfin : les secrets. Terraform a un défaut structurel : le state contient les valeurs nécessaires à la convergence, donc il peut contenir des secrets (mots de passe DB, tokens). Le flag sensitive = true masque l’affichage, pas le stockage. Stratégie réaliste :
- privilégier des références (ARN/ID) plutôt que des secrets bruts ;
- injecter les secrets via un gestionnaire (Vault, KMS + SOPS, secret manager cloud) ;
- réduire la surface : comptes DB par application, rotation, TTL quand possible.
Concrètement, sur une boutique, vous gagnez beaucoup à distinguer :
- secrets d’infra (accès DB, credentials de registry privé, clés d’API critiques) → secret manager + rotation ;
- configuration non secrète (nom de bucket, endpoints, flags) → variables, ConfigMap, ou équivalent.
Si votre boutique PrestaShop (ex. PrestaShop 9.2 + PHP 8.3) tourne sur une infra mutable, la dérive arrive vite : règles firewall modifiées à la main, ports ouverts “temporairement”, certificats copiés à la main. Pour la partie sécurité conteneurs, vous avez déjà un rappel utile côté conformité : CIS Benchmark Docker : exigences clés pour images conteneurisées conformes. Terraform ne remplace pas ces contrôles, mais il permet d’appliquer des garde-fous (security groups, policies IAM, WAF, règles TLS) de façon versionnée.
Conteneuriser proprement : images OCI reproductibles, build déterministe, et limites spécifiques PrestaShop
Un conteneur “qui marche” n’est pas un conteneur “maintenable”. Pour viser le reproductible : base image pinée par digest, dépendances Composer/NPM verrouillées, build multi-stage, et séparation runtime/build. Le format d’image standardisé est celui de l’Open Container Initiative (OCI) : Open Container Initiative (OCI). Tant que vous produisez une image OCI, elle tourne sur Docker, containerd, CRI-O, etc.
Ajoutez quelques garde-fous simples qui évitent 80% des problèmes en prod :
- ne jamais builder en prod (staging/prod pullent une image déjà construite) ;
- exécuter le runtime avec un utilisateur non root quand c’est possible (et gérer proprement les UID/GID sur volumes) ;
- interdire les secrets dans l’image (pas de
.env“par commodité”, pas de clés API en build-arg) ; - documenter ce qui est persistant vs jetable.
Sur PrestaShop, vous devez être honnête sur les zones persistantes : /img, /download, /upload, et parfois des caches applicatifs si vous n’externalisez pas correctement. Le cœur PrestaShop n’a pas été pensé “cloud-native” : si vous mettez tout dans l’image, vous perdez les assets au redéploiement ; si vous mettez tout dans un volume, vous perdez l’immuabilité.
Une manière pragmatique de clarifier (et de mieux découper vos sauvegardes) :
| Élément | Doit survivre à un redeploy ? | Solution fréquente |
|---|---|---|
| Base de données | Oui | Managed DB / VM dédiée + backups |
/img (médias produits) |
Oui | Volume persistant / NFS / objet + sync maîtrisé |
| Sessions | Non (idéalement) | Redis |
| Cache (Smarty, cache HTTP) | Non | Redis / cache externe / purge contrôlée |
| Code + dépendances | Non (artefact immuable) | Image OCI |
Une architecture réaliste en conteneurs :
- stockage persistant externalisé (volume, NFS, ou object storage avec sync maîtrisé) pour les médias ;
- sessions et cache dans Redis (et pas en filesystem) ;
- base MariaDB hors conteneur en production (managed DB ou VM dédiée), pour isoler la persistence.
Sur la partie sécurité “conteneurs”, si vous avez besoin d’un cadre reconnu (notamment pour parler à des équipes conformité/GRC), la publication NIST est une référence stable : NIST SP 800-190 — Application Container Security Guide (2017). Elle ne remplace pas vos contraintes métier, mais elle aide à structurer : surface d’attaque de l’image, isolation runtime, gestion des vulnérabilités, registre, etc.
En local et en staging, Docker Compose reste efficace pour coller à la prod sans y passer 3 jours. Si vous cherchez une méthode qui évite les environnements “presque comme prod mais pas vraiment”, partez de ce pattern : Staging PrestaShop : créer un environnement Docker fidèle à la production et complétez avec Docker Compose : orchestrer des services multi-conteneurs en production. Point de vigilance : Compose en prod fonctionne, mais impose une discipline (healthchecks, restart policies, logs, backups, rotation secrets) que beaucoup d’équipes sous-estiment — surtout quand la boutique grandit (plus de trafic, plus de jobs cron, plus de modules tiers).
Côté debugging, les conteneurs ajoutent une couche d’indirection (réseau, volumes, user IDs). Pour PHP, votre gain de temps dépend surtout d’un débogage stable dès le départ : Xdebug VS Code : configurer le débogage PHP pas à pas. Sans ça, vous perdez vos soirées à “ça marche sur ma machine” alors que le problème est juste un mapping de path, un reverse proxy mal configuré, ou une résolution DNS interne différente.
Où s’arrête Terraform et où commence l’orchestration : Compose, Kubernetes, et l’anti-pattern du « tout dans HCL »
Le point de bascule, c’est la surface opérationnelle : quand vous commencez à avoir plusieurs services, du scaling horizontal, des rollouts, des secrets dynamiques, et des besoins de self-healing, un orchestrateur devient rationnel. Kubernetes est défini simplement ainsi : « Kubernetes … is an open-source system for automating deployment, scaling, and management of containerized applications. » (Kubernetes overview). Ça ne veut pas dire “Kubernetes partout”, ça veut dire : utilisez-le quand vos contraintes l’exigent.
Un repère utile (sans dogme) :
- Compose : 1–5 services, scaling limité, besoins réseau simples, équipe petite, priorité à la vitesse.
- Kubernetes : plusieurs environnements, exigences de résilience, déploiements fréquents, besoin d’auto-réparation, séparation forte des responsabilités, ou contraintes de gouvernance (policies, namespaces, RBAC).
Terraform, dans ce tableau, sert à : créer le cluster (ou l’infra support), le réseau, les load balancers, le DNS, les volumes, les policies IAM. Le déploiement applicatif (images, manifests, Helm/Kustomize, policies runtime) doit idéalement passer par un flux GitOps (Argo CD/Flux) ou un pipeline CI/CD dédié.
Nuance importante : utiliser Terraform pour bootstrapper des composants “socle” Kubernetes (ingress controller, cert-manager, CSI driver, external-dns) peut se défendre si vous maîtrisez les cycles de vie et que vous isolez clairement cette couche. Là où ça dérape, c’est quand :
- vous gérez toute l’app (deployments, services, config, secrets) dans Terraform,
- dans le même state que le réseau/LB/DNS,
- avec des diffs applicatifs qui changent plusieurs fois par jour.
Sinon, vous retombez sur l’anti-pattern classique : Terraform applique des ressources Kubernetes, et vous mélangez l’état infra + applicatif dans un state unique. Résultat : plans lents, diffs incompréhensibles, et rollbacks douloureux.
Pour PrestaShop, la migration vers Kubernetes a des pièges spécifiques (multiboutique, TLS, DNS, sessions, fichiers). Si vous êtes déjà dans cette trajectoire, appuyez-vous sur deux checklists internes du site : Migration PrestaShop vers Kubernetes : checklist GitOps et pièges courants et Migration PrestaShop Kubernetes : TLS, DNS et configuration multiboutique. Vous verrez vite que “dockeriser” n’est qu’une étape ; la difficulté est la statefulness (fichiers + DB) et la gestion réseau/TLS sans casser l’URL canonique.
Déploiements reproductibles : pipeline, registries, SBOM, et rollback réel (pas théorique)
Le contrat DevOps minimal : un commit donné doit produire un artefact donné, déployable de manière traçable. En conteneurs, l’artefact est l’image (tag immuable, idéalement digest), poussée dans un registry (GHCR, GitLab, ECR, Harbor…). Vos environnements (staging/prod) ne “buildent” jamais : ils pullent. C’est le seul moyen d’éviter qu’une mise à jour de dépendance transitive change votre runtime sans commit.
Un pipeline lisible (et auditable) ressemble souvent à ça, même si les outils varient :
- Lint + tests (PHPUnit, statique, lint Dockerfile si vous le faites)
- Build image (multi-stage, dépendances lockées)
- Scan (vulnérabilités OS + libs)
- SBOM (CycloneDX/SPDX) + archivage
- Push registry (tag + digest)
- Signature (si vous appliquez une politique de confiance)
- Déploiement staging + smoke tests
- Promotion prod (même digest) + stratégie de rollout
Côté Terraform, la reproductibilité passe par : terraform fmt + validate, tflint, policy-as-code (OPA/Conftest ou Sentinel si vous êtes sur l’écosystème HashiCorp), puis plan en CI et apply contrôlé. Le mécanisme utile ici n’est pas “automatiser à 100%”, c’est garantir que le plan est celui qui sera appliqué (même commit, même provider versions, même backend, même variables). Pour un e-commerce, l’erreur fréquente est de laisser latest partout (images, providers, modules), puis de découvrir le jour J qu’un upgrade implicite casse le LB, change un comportement TLS, ou modifie des labels.
Sur la supply chain, ne vous racontez pas d’histoire : en 2026, un build sans SBOM et sans scan est un angle mort. Le site a déjà cadré le sujet côté PrestaShop : PrestaShop : sécuriser APIs et modules avec SBOM, WAF et CI/CD. Appliquez le même principe aux images : générez une SBOM (CycloneDX/SPDX), scannez (Trivy/Grype), signez (cosign) et bloquez en CI si vulnérabilité critique exploitable.
Le rollback doit être un rollback d’image (digest précédent) + une stratégie DB (migrations compatibles ou rollback planifié), sinon ce n’est pas un rollback, c’est un “retour au chaos”. Sur une boutique, les points qui cassent le plus souvent les retours arrière :
- migrations SQL non rétro-compatibles (suppression/rename de colonnes sans plan),
- jobs asynchrones qui réécrivent des données (indexation, imports),
- cache/CDN qui continue à servir des assets incompatibles.
Observabilité et exploitation : drift, métriques, logs, et runbooks qui tiennent en prod
L’IaC et les conteneurs réduisent le bruit, mais n’éliminent pas les incidents. Pour piloter, vous avez besoin d’observabilité cohérente : métriques (Prometheus), logs (centralisés), traces si possible, et alerting actionnable. Le plus important : corréler l’événement avec un changement (déploiement image, apply Terraform, rotation de secret). Sans ça, votre MTTR explose.
Côté métriques, partez sur des signaux simples et vérifiables : saturation CPU/mémoire, latence Nginx/PHP-FPM, saturation DB, taux d’erreurs 5xx, temps de réponse checkout. Ensuite seulement, affinez. Pour l’outillage, deux références internes aident à construire une base solide : Prometheus : configuration des alertes, métriques et requêtes PromQL et Netdata : intégrer Prometheus, SNMP et StatsD pour tout surveiller. Netdata est souvent utile pour “voir vite” en incident, Prometheus pour industrialiser les alertes.
Ajoutez un réflexe “runbook-first” : une alerte doit pointer vers une procédure courte qui répond à trois questions :
- Que vérifier en premier ? (ex : saturation DB, pool PHP-FPM, quotas disque du volume médias)
- Qu’est-ce qui a changé ? (dernier digest déployé, dernier
apply, rotation secret, changement DNS) - Quelles actions sont sûres ? (rollback d’image, scale horizontal, bascule read-only, purge cache)
Enfin, le drift : si vous n’exécutez jamais terraform plan en lecture seule sur la prod, vous ne savez pas si quelqu’un a modifié une règle réseau à la main ou si un composant managé a changé de comportement. Mettez un job plan quotidien (sans apply), alertez sur changement non attendu, et documentez un runbook.
Et n’oubliez pas la dimension “données” (très concrète en France/UE) : vos logs et traces peuvent contenir des données personnelles (IP, identifiants, URLs). Si vous avez des clients UE, le cadre légal de référence reste le RGPD (Règlement (UE) 2016/679) — ce qui implique, côté ops, de maîtriser la rétention, les accès, et les transferts hors UE le cas échéant. Ce n’est pas un sujet “juridique abstrait” : c’est une exigence qui influence où vous stockez les logs, qui peut y accéder, et combien de temps.
Sur PrestaShop, la moindre divergence de TLS/DNS peut avoir des effets SEO et UX immédiats ; si vous touchez à HTTPS/certificats, recoupez avec vos exigences de durcissement (par ex. HTTPS SEO : bonnes pratiques, certificats SSL et audit technique).
Checklist opérationnelle (sans “best practices” creuses) pour une infra PrestaShop IaC + conteneurs
Commencez par verrouiller le socle : versions explicites (Terraform 1.x, providers pinés, images pinées), backend distant chiffré, et une convention de naming/tagging. Si vous êtes sur un hébergeur type VPS/dédié, clarifiez ce que Terraform peut piloter (API provider) et ce qui restera en configuration management (Ansible) ou en image (Packer). Sur un dédié “à la main” sans API, Terraform n’aura qu’un intérêt limité ; dans ce cas, focalisez sur conteneurs + CI/CD + observabilité, et documentez la configuration système.
Ensuite, traitez le cas PrestaShop sans magie : externalisez l’état (DB, médias), rendez l’app stateless (sessions Redis), et automatisez les tâches de maintenance (cron, indexation, purge). Pour éviter les erreurs récurrentes en prod (permissions, volumes, uid/gid), préparez des checks automatisés.
Checklist courte, orientée “éviter l’incident” :
- Artefacts : un commit → une image (digest), déployée telle quelle en staging puis promue en prod.
- Persistence : DB backup testés + restauration testée ; médias sauvegardés (et versionnés si possible).
- Secrets : jamais dans l’image, jamais en clair dans le state ; rotation planifiée.
- Réseau/TLS : DNS/TLS pilotés et revus ; pas de changement manuel non tracé.
- Drift : plan quotidien + alerte ; revue des exceptions (si vous acceptez du “break-glass”, documentez-le).
- Rollback : retour arrière = digest précédent + plan DB (compatibilité ou procédure).
Si vous êtes déjà confronté à des erreurs 500 en production, ne cherchez pas à “réparer avec Terraform” : diagnostiquez d’abord les causes applicatives et runtime (voir Erreur 500 PrestaShop : 10 causes fréquentes et solutions rapides).
Terminez par l’exploitation : un déploiement doit être observable (dashboards + logs), réversible (rollback image), et auditable (qui a appliqué quoi, quand). Pour un e-commerce, le critère n’est pas “on a de l’IaC”, c’est : combien de temps pour recréer un staging identique, combien de temps pour corriger une dérive, et combien de temps pour revenir à un état sain après un incident. Si vos réponses sont vagues, c’est que l’IaC est encore du texte dans Git, pas un système de production.




