Une vérification de sécurité IaC (Infrastructure as Code, c.-à-d. infrastructure versionnée sous forme de code) peut sembler au premier abord « seulement un contrôle supplémentaire dans la pipeline ». En pratique, c’est un concept d’exploitation : elle détermine en partie si les modifications RESTent traçables, si des secrets s’écoulent inaperçus depuis les fichiers d’état, et si votre état réel dans le cloud ou le centre de données correspond encore à ce qui se trouve dans le dépôt. C’est précisément dans des environnements où plusieurs équipes travaillent sur les réseaux, l’IAM (Identity and Access Management, c.-à-d. la gestion des droits et des rôles) et les services plateforme que les risques proviennent moins d’une « magie des hackers » que de responsabilités floues, de contournements oubliés et d’autorisations trop larges.
Ce billet présente une approche solide pour les administrateurs, system engineers et pRESTataires techniques : ancrer de manière pertinente le Terraform-Scanning dans la CI/CD, protéger les fichiers d’état (y compris les pièges typiques liés aux backends et aux logs) et exploiter la Drift-Detection de sorte qu’elle ne se transforme pas en bruit d’alerte, mais fonctionne comme un système d’alerte précoce pour les écarts de sécurité et d’exploitation. L’accent n’est pas mis sur le marketing des outils, mais sur la mise en œuvre, les limites, le dépannage et une stratégie de repli réaliste.
Pourquoi la vérification de sécurité IaC échoue dans la pratique (et comment l’éviter)
Dans de nombreuses organisations, la sécurité IaC est introduite de manière ponctuelle : un scanner s’exécute une fois, génère une longue liste de findings, puis la piste se perd. Causes typiques :
- Définition de « Definition of Done » peu claire : Qu’est-ce qui constitue un blocage, qu’est-ce qui relève d’une acceptation du risque, qu’est-ce qui peut être corrigé ultérieurement ?
- Absence de baseline : Sans « Golden Rules » (par ex. pas d’ouverture 0.0.0.0/0 sur les ports d’administration, journalisation obligatoire, chiffrement at REST), chaque finding peut être discuté.
- État comme angle mort : Le tfstate contient souvent plus d’informations que prévu, y compris des attributs sensibles — et est pourtant traité comme un artefact de build.
- Drift sans ownership : Les rapports de drift tombent dans le néant parce que personne ne clarifie si l’écart était intentionnel, un incident ou un correctif d’urgence.
Une configuration durable relie trois niveaux : (1) contrôles préventifs avant l’apply (scanning/policies), (2) protection des données de contrôle (state, credentials, logs), (3) contrôles détectifs en exploitation (drift, audit, alerting). Ce n’est qu’ensemble que l’on obtient un gain de sécurité qui tient dans le quotidien.
Bloc 1 : Introduire correctement le Terraform-Scanning — avec des gates clairs plutôt qu’une avalanche de findings
Par « Terraform-Scanning » on entend ici : analyse statique de vos définitions IaC (HCL), parfois complétée par une analyse du plan (évaluation du „terraform plan“) afin de détecter tôt les mauvaises configurations et les anti-patterns de sécurité. Important : un scanner ne voit que ce qu’il peut interpréter. Son efficacité dépend de où vous scannez et de ce que vous définissez comme « non négociable ».
Niveaux d’analyse : Pre-Commit, Pull Request, Merge Gate, Nightly
Pour l’exploitation, un modèle en plusieurs niveaux s’avère efficace :
- Pre-Commit (local) : Rapide, mais non contraignant. Utile pour le formatage, les erreurs évidentes et les premiers signaux de politique.
- Pull-Request-Checks : Le point central pour la vérification de la sécurité IaC. Les résultats peuvent être relus et liés aux changements.
- Merge Gate : Règles strictes (par ex. « Public Exposure », « pas de buckets non chiffrés », « pas de rôles admin »).
- Nightly/périodique : Rattrapage pour les modules externes, nouvelles règles, nouvelles CVE dans les provider-plugins (si vous vérifiez aussi les aspects de la supply chain).
Il est important de distinguer les violations de politique (doivent bloquer) et les avertissements (doivent rester visibles comme dette technique). Si tout bloque, le scanning sera contourné ; si rien ne bloque, il ne sert à rien.
Analyse basée sur le plan : pourquoi „terraform plan“ reflète mieux la réalité
Les contrôles statiques ne voient souvent pas quelles valeurs sont effectivement appliquées (variables, modules, valeurs par défaut). L’analyse basée sur le plan utilise le plan Terraform comme produit intermédiaire pour vérifier concrètement quelles ressources sont créées avec quels attributs. En exploitation, c’est particulièrement utile pour :
- Paysages de modules (beaucoup d’abstractions, peu de defaults visibles)
- Setups multi-environnements (Dev/Stage/Prod avec des inputs différents)
- Risque hérité provenant de modules partagés
Condition préalable : qu’un plan puisse être généré dans la CI sans exfiltrer de secrets ni ouvrir des accès productifs. Cela amène directement la question des credentials, des workspaces et des rôles isolés (principe du moindre privilège).
Flux CI minimal avec sortie du plan en tant qu’artefact (sans spécifier d’outil dans l’article)
Indépendamment du système CI, un modèle robuste : Init → Validate → Plan → Scan du plan → Résultat sous forme de rapport. Veillez à ce que les artefacts de plan soient protégés (droits d’accès, rétention). Un exemple en Bash pour une étape générique de pipeline :
set -euo pipefail
# Im CI: keine interaktiven Prompts
export TF_IN_AUTOMATION=1
terraform fmt -check -recursive
terraform init -input=false
terraform validate
# Plan erzeugen und als JSON exportieren (für plan-basiertes Scanning)
terraform plan -input=false -out=tfplan
terraform show -json tfplan > tfplan.json
# Hinweis: tfplan.json als Artefakt nur intern und kurzzeitig aufbewahren
# Scanner-Aufruf wäre hier (toolabhängig), Ergebnis als CI-Report publizierenQuand cela échoue-t-il ? Souvent lorsque l’authentification des providers n’est pas correctement séparée (par ex. des credentials développeur dans la CI), lorsque des modules interrogent des sources de données externes au moment du plan, ou lorsque des backends distants sont configurés sans locking / sans droits corrects.
Pièges lors de l’analyse Terraform
- Faux positifs dus à une perte de contexte : Un scanner « voit » une Security Group ouverte, mais pas qu’elle n’existe que dans une VPC de test isolée. Solution : tags/labels d’environnement cohérents, règles différenciées, exceptions documentées.
- „Ausnahmen“ ohne Ablaufdatum: Les ouvertures temporaires deviennent permanentes. Lösung: processus d’exception mit Ticket, Owner, Ablaufdatum, Review.
- Module aus fremden Quellen: Risiken aus Supply Chain (unerwartete Ressourcen, alte Patterns). Lösung: Module pinnen (Versionen), Quellen kontrollieren, periodisch re-auditieren.
- Scanner blockt, aber niemand weiß warum: Ohne verständliche Reports und klare Remediation-Hinweise wird die Pipeline zum Reibungspunkt.
Baustein 2: Terraform State-Files schützen – weil tfstate oft sensible Daten enthält
Der Terraform State (tfstate) ist der Abgleich zwischen „gewünschtem Zustand“ und „tatsächlich vorhanden“. Im State stehen Resource-IDs, Metadaten, Abhängigkeiten – und je nach Provider auch Attribute, die Sie nicht in Git sehen wollen. Selbst wenn Terraform Felder als sensitive markiert, ist das kein Freifahrtschein: Das State-File bleibt ein hochkritisches Asset, weil es Infrastrukturzugriffe indirekt erleichtert (Reconnaissance) und manchmal echte Secrets enthält.
Was im State typischerweise kritisch ist
- Netzwerk-Topologie: Subnetze, Routing, Security Groups, interne DNS-Namen
- IAM-Details: Rollen, Policy-Arns/IDs, Vertrauensbeziehungen
- Endpunkte: Datenbank-Hosts, Load Balancer, interne Services
- Konfigurationswerte: je nach Ressource auch Passwörter, Tokens, Private Keys (schlechter Fall), User-Data-Inhalte
Die Konsequenz ist klar: State gehört in eine kontrollierte Ablage mit Verschlüsselung, Zugriffskontrolle, Versionierung und Locking. „Im Repo“ oder „als CI-Artefakt“ ist in produktiven Umgebungen fast immer falsch.
Remote State Backend: Verschlüsselung, Zugriff, Locking, Versionierung
Ein Remote Backend (z. B. Object Storage, Terraform Cloud/Enterprise, oder ein eigener Backend-Service) ist nicht nur Komfort, sondern Sicherheits- und Betriebsgrundlage. Prüfen Sie diese Eigenschaften:
- Verschlüsselung at REST: Serverseitig (KMS/Key-Management) oder clientseitig. Wichtig ist Key Governance (Rotation, Zugriff, Audit).
- Transportverschlüsselung: TLS muss obligatorisch sein, inklusive korrekter Zertifikatsprüfung auf Clients.
- Locking: Verhindert parallele Applies, die State korrupt machen. Ohne Locking entstehen schwer reproduzierbare Drift- oder „Phantom“-Änderungen.
- Versionierung: Ermöglicht Rollback, forensische Rekonstruktion und Recovery nach Fehlern.
- Striktes IAM: Nur CI-Rolle und wenige Operatoren erhalten Zugriff; getrennte Rechte für Read vs. Write.
Konkrete Betriebs-Checks: Wo State gerne unbemerkt „mitläuft“
In der Praxis taucht tfstate an Stellen auf, die bei Security Reviews gerne übersehen werden. Eine kurze Checkliste:
- Developer-Home-Verzeichnisse: fichiers State locaux issus de tests, qui finiront plus tard dans des sauvegardes
- CI-Workspaces: disques des runners, caches, stockages d’artefacts, logs de débogage
- Ticket-Anhänge: « Peux-tu jeter un œil ? » – et quelqu’un attache tfstate ou tfplan.json
- Log-Aggregation: logs trop verbeux contenant des détails de Plan/State
Une vérification pratique consiste à rechercher de manière ciblée des signatures typiques (p. ex. noms de fichiers, clés JSON). Exemple pour un Linux-Runner (adapter le chemin) :
set -euo pipefail
# Vorsicht: nur auf Systemen ausführen, für die Sie berechtigt sind.
# Sucht nach typischen Terraform-State-Dateinamen in Workspaces und Caches.
find /var/lib -type f ( -name "*.tfstate" -o -name "*.tfstate.backup" -o -name "tfplan.json" ) 2>/dev/nullSi vous trouvez des éléments, le travail de suivi est essentiel : pourquoi ont-ils été générés, pourquoi n’ont-ils pas été nettoyés, et comment éviter une récurrence (nettoyage des workspaces, durcissement des runners, rétention des artefacts).
Séparer proprement l’accès au State : opérateurs, CI et Break-Glass
« Least Privilege » signifie, dans le contexte IaC : la pipeline ne doit pouvoir appliquer que ce qui lui est nécessaire dans son périmètre — et pas plus. Pour l’accès au State et les droits d’Apply, trois rôles se sont révélés utiles :
- Rôle CI-Apply : accès en écriture au State + droits sur les ressources dans le projet/compte/subscription concerné. Pas d’accès interactif par login.
- Rôle Read-Only-Audit : peut lire le State (ou les rapports), mais pas écrire ; adapté pour la sécurité/la conformité.
- Rôle Break-Glass : accès d’urgence fortement protégé (MFA, Just-in-Time, journalisation stricte), pour permettre des corrections critiques en cas de panne de pipeline.
L’important est le concept d’exploitation : le Break-Glass doit exister, mais être rarement utilisé. Et chaque utilisation doit être visible dans les processus de drift et de change, sinon vous créez des « Shadow Changes ».
Stratégie de repli en cas de State compromis
Si vous devez partir du principe qu’un fichier State a fuité, traitez cela comme un incident de sécurité : le State permet de la reconnaissance et peut, selon les ressources, contenir de véritables secrets. Une stratégie de repli sensée comprend :
- Bloquer les accès : faire tourner les clés/tokens d’accès au backend, désactiver les rôles concernés.
- Faire tourner les secrets exposés : mots de passe de base de données, tokens API, clés SSH, selon le soupçon. Ne pas attendre d’avoir des « preuves ».
- Durcir le backend : vérifier les chemins d’accès, activer le logging/l’audit, ajuster la rétention et les alertes.
- RESTaurer le State : choisir dans le backend versionné un point de RESTauration défini. Ensuite exécuter Plan/Apply de manière contrôlée.
- Travail post-incident : pourquoi le secret se trouvait-il dans le State ? Souvent la cause est « secret en tant qu’attribut de ressource » ou « user-data contient des identifiants ».
Important : tous les leaks n’imposent pas de reprovisionner toutes les ressources. Mais toute possibilité que de véritables secrets aient été dans le State exige une rotation. Si vous ne pouvez pas effectuer de rotation, c’est un problème de conception de vos solutions numériques d’entreprise (p. ex. absence de cycle de vie des secrets) — et cela doit être priorisé.
Composant 3 : détection de dérive en exploitation – du « noise » aux écarts fiables
La détection de dérive signifie : vous comparez régulièrement l’état souhaité déclaratif (IaC) avec l’état réel dans l’environnement cible. Une dérive survient lorsqu’une personne modifie manuellement la console cloud, vCenter, le gestionnaire de pare-feu ou via un script apporte des changements qui ne figurent pas dans le code. Toutes les dérives ne sont pas néfastes – mais toute dérive est un signal : soit le processus est cassé, soit la définition IaC n’est plus la vérité.
Quelles dérives sont vraiment pertinentes (priorisation pour l’exploitation)
Il est recommandé de prioriser selon l’impact :
- Drift de sécurité : ouverture de ports, modification des politiques IAM, désactivation de la journalisation, suppression du chiffrement, modification des relations de confiance.
- Drift de disponibilité : paramètres d’échelle, health checks, cibles DNS/load-balancer, classes de stockage.
- Drift de coûts/ressources : tailles d’instances, limites d’auto-scaling, ressources nouvelles inattendues.
- « Simplement » métadonnées : tags/labels, descriptions ; important pour la gouvernance, mais rarement critique immédiatement.
Si vos rapports de dérive traitent tout de la même manière, des écarts critiques seront négligés. L’objectif est un modèle de triage : qu’est-ce qui doit aller immédiatement dans le processus Incident/Change, qu’est-ce qui peut être placé dans le sprint suivant, qu’est-ce qui est une « expected drift » (p. ex. des identifiants automatiques du provider) et doit être supprimé ?
Mettre en œuvre la détection de dérive techniquement : plan périodique sans Apply
Un schéma pratique consiste en un job périodique (p. ex. quotidien) qui exécute par Workspace/Environment un init/refresh/plan et vérifie s’il y a des modifications en attente. Important : vous n’exécutez aucun Apply, mais générez un signal. Exemple (Bash) comme base :
set -euo pipefail
export TF_IN_AUTOMATION=1
terraform init -input=false
# Plan ohne interaktives Apply; Exitcode 2 bedeutet: es gäbe Änderungen
terraform plan -input=false -detailed-exitcode -out=tfdriftplan || rc=$?
rc=${rc:-0}
if [ "$rc" -eq 2 ]; then
echo "DRIFT_DETECTED=1"
terraform show -no-color tfdriftplan > drift.txt
# Hier: an Ticket/Alerting übergeben, aber drift.txt als sensitives Artefakt behandeln
exit 0
elif [ "$rc" -eq 0 ]; then
echo "DRIFT_DETECTED=0"
exit 0
else
echo "Terraform plan failed with exit code $rc" 1>&2
exit "$rc"
fiPourquoi cela fonctionne-t-il ? Terraform calcule si l’état actuel (respectivement l’état réel déterminé par le Refresh) diffère de l’état souhaité. Quand cela échoue-t-il ? Lorsque les Provider-APIs subissent du rate-limiting, lorsque les Credentials expirent, lorsque les sources de données sont peu fiables ou lorsque le State lui-même est incohérent (p. ex. après des modifications parallèles sans Locking).
Ancrer la détection de dérive sur le plan organisationnel : Owner, Runbook, fenêtres temporelles
La meilleure détection de dérive ne sert à rien sans réaction claire. Définissez :
- Owner pro Stack/Workspace: Qui décide si la dérive doit être annulée ou intégrée dans l’IaC ?
- Temps de réaction selon la classe de dérive : la dérive de sécurité est traitée plus rapidement que la dérive quotidienne.
- Fenêtre de maintenance : De nombreuses dérives ne peuvent être nettoyées correctement que pendant la fenêtre de changement.
- Runbook : Que vérifions‑nous en premier (journaux d’audit, tickets de changement, derniers runs de pipeline) ?
En tant qu’exploitant, vous devez également accepter : une partie de la dérive résulte de l’automatisation de la plateforme (p. ex. des Managed Services qui ajustent automatiquement des paramètres). Vous devez connaître ces effets et les filtrer de manière ciblée, sinon vous générerez des alertes continues.
Flux de travail de bout en bout : examen de sécurité IaC comme routine opérationnelle
Mettez en œuvre les trois éléments dans un processus continu. Un modèle opérationnel réaliste ressemble à :
- Préparation : définir les règles de base (bloqueur vs avertissement), responsabilités, processus d’exception.
- Intégration CI : Validate + Plan + Scanning (HCL et/ou Plan), rapports dans la PR, bloqueurs comme gate.
- Renforcement de l’état : backend distant avec verrouillage et versioning, IAM strict, hygiène des artefacts et des logs.
- Dérive en exploitation : plan périodique, classification, tickets/alerting, boucle de revue.
- Maintenance des règles : introduction contrôlée de nouvelles politiques, nouvelles fonctionnalités des fournisseurs, nouvelles exigences (p. ex. obligation de logging).
Liste de contrôle : Ce que vous pouvez accomplir la première semaine de manière réaliste
- Définir les 10 règles bloqueuses principales (ports admin exposés publiquement, pas de buckets de stockage ouverts, logging activé, chiffrement activé, IAM pas de « * »).
- Activer les checks PR : fmt/validate + un scanner + génération de rapport.
- Vérifier le backend d’état : locking, versioning, contrôle d’accès, rétention.
- Hygiène des CI runners : supprimer le workspace après le job, minimiser les artefacts, ne pas rendre les logs trop verbeux.
- Déployer le job de drift en pilote pour un environnement (p. ex. Stage) et définir le canal d’alerte.
Dépannage : scénarios d’erreur fréquents et mesures correctives rapides
1) Le scanner signale « critique », mais c’est un design intentionnel
Exemple : un service doit être accessible publiquement délibérément. Solution : ne pas « fermer » l’alerte, mais documenter les contrôles compensatoires (WAF, limitation de débit, mTLS derrière un proxy, durcissement du groupe de sécurité sur ports/sources). Exception avec date d’expiration et propriétaire. Vérifier si vous pouvez préciser la règle (p. ex. seulement certains types de ressources).
2) La détection de dérive se déclenche constamment à cause de changements « managed »
La cause est souvent un Managed Service qui ajuste automatiquement des paramètres (p. ex. IDs, valeurs par défaut mineures). Contre‑mesures :
- Utiliser de façon ciblée les mécanismes lifecycle/ignore (mais seulement pour les champs réellement « bruit »).
- Pinner les versions des fournisseurs et mettre à jour de manière contrôlée (sinon les valeurs par défaut changent).
- Adapter la classification des dérives : dérive de métadonnées ≠ dérive de sécurité.
3) Problèmes de state-locking et « stuck locks »
Le locking empêche les modifications parallèles, mais peut « bloquer » si un job s’interrompt. La contre‑mesure est un Runbook défini : vérifier le lock, identifier le propriétaire, ne supprimer le lock qu’en cas d’urgence, puis exécuter un contrôle de cohérence (Plan). À long terme : concevoir les jobs CI pour qu’ils se terminent proprement (timeouts, stratégie de retry, pas d’apply parallèle sur le même workspace).
4) Le plan en CI échoue car les credentials sont manquants ou trop permissifs
La séparation et le principe du moindre privilège aident ici : pour Plan/Read, des droits moindres suffisent souvent par rapport à Apply. Si vous réglez les deux avec un rôle tout‑puissant, vous gagnez en stabilité à court terme, mais perdez en sécurité. Mieux : des rôles séparés, et si Plan a besoin d’APIs Read spécifiques, les ajouter de façon ciblée.
Aspects de sécurité et de conformité que les administrateurs ont tendance à négliger
IaC est souvent classé comme un « sujet DevOps », mais il est central pour l’audit et l’exploitation. Veillez à :
- Traçabilité : Qui a approuvé quelle modification d’infrastructure et quand ? PR-Reviews, logs de pipeline et audits du backend doivent être cohérents.
- Protection de la couche de contrôle : CI/CD fait partie de votre sécurité en production. Runner, Secrets, Token-Scopes, accès réseau.
- Minimisation des données : Plan/State/Reports contiennent des détails. Conservez uniquement ce dont vous avez besoin pour l’exploitation et l’audit, et seulement aussi longtemps que nécessaire.
- Ségrégation des environnements : Dev/Prod pas seulement logique, mais via des comptes/Subscriptions/projets séparés, des States séparés, des clés séparées.
Si vous procédez parallèlement au durcissement de clusters ou de bases de données, l’effet d’apprentissage est élevé : de nombreux principes (Least Privilege, Audit-Logs, Recovery-Tests) sont identiques, seuls les outils diffèrent. Des liens internes vers les guides d’exploitation voisins sont appropriés.
Conclusion : l’audit de sécurité IaC est un processus opérationnel, pas un scan ponctuel
Un audit de sécurité IaC efficace naît quand vous concevez le scanning, la protection du State et la détection de dérive comme un système opérationnel cohérent : préventif (gates dans les PRs), protecteur (State/Artefakte/Runner), détectif (dérive avec réaction claire). L’effort repose moins sur les outils que sur des responsabilités claires, quelques règles strictes et la discipline de limiter les exceptions dans le temps.
Si vous mettez cela en place ainsi, vous obtenez plus que des « cases Compliance » : vous réduisez les risques de sécurité liés aux erreurs de configuration, détectez plus tôt les modifications non autorisées ou oubliées et pouvez réagir plus rapidement et de manière plus fiable en cas d’incident, car l’historique de votre infrastructure est traçable.
Pour ce sujet, la protection du Terraform State et la détection de dérive sont également importantes. Cet article place ces aspects de manière compréhensible et montre ce qui compte au quotidien.