Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

⚙️DevOps – Terraform, State, GitLab CI/CD & Gestion d'incidents (Part 1)

Guide pratique IDEO‑Lab pour nouveaux DevOps : infrastructure as code, modules, state, pipelines, déploiement contrôlé et production.

1.1

Vue d'ensemble DevOps

Le rôle DevOps côté infra : automatiser, fiabiliser, tracer et sécuriser.

CultureInfraProd
1.2

Terraform : bases solides

Providers, resources, variables, outputs, plan/apply et cycle de vie.

IaCPlanApply
1.3

Modules Terraform

Découper proprement réseau, compute, sécurité, base de données et applicatif.

ReusableVPCCompute
1.4

State Terraform

Backend distant, locking, dérive, isolation par environnement et sécurité.

StateLockDrift
2.1

GitLab CI/CD Infra

Stages fmt, validate, plan, review, apply et rollback contrôlé.

GitLabPipelineRunner
2.2

Environnements

Dev, staging, prod : variables protégées, branches, approvals et séparation.

DevStagingProd
2.3

Secrets & sécurité CI

Variables masquées, scopes, credentials courts, policy least privilege.

SecretsOIDCIAM
2.4

Déploiement infra

Workflow propre : changement, revue, plan, fenêtre de prod, apply et vérification.

ChangeReviewVerify
3.1

Observabilité

Logs, métriques, alertes, traces et tableaux de bord pour piloter la production.

LogsMetricsAlerts
3.2

Incidents production

Qualifier, mitiger, restaurer, communiquer, analyser et éviter la récidive.

IncidentRCAPost‑mortem
1.1 DevOps Infrastructure Overview
What infrastructure DevOps really means

Infrastructure DevOps is not only about deploying servers. It is about building platforms and delivery processes that are repeatable, auditable, secure, observable, and resilient.

The goal is simple: if production breaks, or a new environment is needed, the team must be able to rebuild or change it from code, with controlled automation, clear approvals, and full traceability.

Professional objective: move from fragile manual operations to a platform model driven by Git, Terraform, pipelines, monitoring, and incident discipline.
Core responsibilities
AreaWhat DevOps handles
ProvisioningCreate VPCs, subnets, compute, IAM, load balancers, databases, DNS, storage.
AutomationTurn infrastructure changes into reviewed code and pipelines.
ReliabilityKeep services available and reduce operational risk.
SecurityApply least privilege, secrets hygiene, network controls, auditability.
ObservabilityProvide logs, metrics, traces, dashboards, alerts, and health checks.
Incident responseRestore service fast, communicate clearly, then drive root cause analysis.
The 6 professional pillars
PillarProfessional expectation
Infrastructure as CodeNo critical production resource should exist only in a cloud console.
Delivery disciplineEvery change goes through branch, merge request, plan, review, approval, apply.
State managementTerraform state is remote, protected, versioned, and locked.
Security baselineLeast privilege, secrets not stored in Git, protected runners, approvals.
ObservabilityDashboards and alerts exist before the incident, not after.
RunbooksCommon incidents have written procedures and rollback instructions.
High-level delivery diagram
Engineer / Platform Team
                            │
                            ▼
                            Git branch
                            │
                            ▼
                            Merge Request
                            │
                            ├── terraform fmt
                            ├── terraform validate
                            ├── linter / security checks
                            ├── terraform plan
                            └── policy checks
                            │
                            ▼
                            Human review of the plan
                            │
                            ▼
                            Approval gate
                            │
                            ▼
                            terraform apply
                            │
                            ▼
                            Post-deploy verification
                            ├── service health
                            ├── logs
                            ├── metrics
                            └── rollback readiness
Golden rule: production changes must be small, reviewed, and reversible.
What production reality looks like

New DevOps engineers often imagine infrastructure work as “create servers and deploy”. In reality, production means handling multiple environments, permissions, cost controls, on-call pressure, changing business needs, compliance, and failure scenarios.

Typical production stack
Users
                            │
                            ▼
                            DNS / CDN / WAF
                            │
                            ▼
                            Load Balancer
                            │
                            ▼
                            Application Tier
                            ├── container platform / VMs
                            ├── autoscaling
                            └── background workers
                            │
                            ▼
                            Data Tier
                            ├── relational database
                            ├── cache
                            ├── object storage
                            └── search / analytics
                            │
                            ▼
                            Observability Layer
                            ├── metrics
                            ├── logs
                            ├── tracing
                            └── alerting
Production constraints
ConstraintImpact
AvailabilityChanges must avoid downtime or keep it minimal and controlled.
SecurityCredentials, IAM roles, network exposure, and runner hardening matter.
CostDevOps must balance reliability with cloud spending.
ComplianceAudit trails, separation of duties, and approval flows may be mandatory.
RecoveryBackups and restore tests are part of production readiness.
Concrete production scenario
SaaS platform on AWS
  • Public traffic enters through CloudFront or an Application Load Balancer.
  • Application runs on ECS, EKS, or EC2 Auto Scaling groups.
  • Database uses PostgreSQL or MySQL with managed backups.
  • Terraform manages VPC, subnets, security groups, IAM, DNS, compute, and database.
  • GitLab CI/CD validates the Terraform code and applies through protected jobs.
  • Monitoring is done with CloudWatch, Grafana, Prometheus, Datadog, or ELK.
What can go wrong in real life
  • A security group change blocks database access.
  • A Terraform apply recreates a resource because lifecycle was not controlled.
  • A runner with too many permissions applies to the wrong workspace.
  • An alert storm hides the real incident.
  • A manual cloud console change creates drift and breaks the next plan.
Production mindset: success is not “the apply completed”. Success is “the business service remained healthy and measurable after the change”.
Professional toolchain by responsibility
ResponsibilityMain toolsTypical usage
IaCTerraform, Terragrunt, OpenTofuProvision cloud resources, shared modules, environment structure.
CI/CDGitLab CI/CD, GitHub Actions, JenkinsValidate, plan, approve, apply, deploy, rollback.
ContainersDocker, Kubernetes, HelmPackage workloads, orchestrate services, manage releases.
Config managementAnsible, Salt, ChefOS packages, user setup, service configuration.
MonitoringPrometheus, Grafana, Datadog, CloudWatchMetrics, dashboards, alerting, SLO tracking.
LoggingELK, OpenSearch, LokiSearch logs, correlate incidents, root cause analysis.
TracingJaeger, Tempo, Datadog APMLatency analysis across services.
SecretsVault, AWS Secrets Manager, SSM Parameter StoreStore secrets outside Git and outside pipeline logs.
SecurityTrivy, Checkov, tfsec, SnykScan images, Terraform, dependencies, misconfigurations.
Tool selection guidance
If you need...Prefer...
Managed cloud provisioningTerraform modules + remote state + CI pipeline
Server configuration after provisioningAnsible
Kubernetes release managementHelm + GitOps or CI/CD
Fast incident log searchELK / OpenSearch / Loki
Secure secret lifecycleVault or cloud native secret manager
Professional recommendation for beginners
  • Master Linux basics and networking first.
  • Then learn Terraform structure, modules, variables, outputs, remote state.
  • Then learn GitLab CI/CD stages, jobs, variables, artifacts, protected environments.
  • Then learn observability: logs, metrics, alert rules, dashboards, SLOs.
  • Finally, learn incident handling and postmortem writing.
Strong profile progression: Linux + networking + Terraform + GitLab CI/CD + cloud basics + monitoring.
Terraform in real production

Terraform is used to describe cloud infrastructure as code. In a professional setup, code is organized into reusable modules, state is stored remotely, environments are clearly separated, and applies are done through controlled pipelines.

Typical module breakdown
live/
                            prod/
                            network/
                            security/
                            app/
                            data/
                            staging/
                            network/
                            security/
                            app/
                            data/
                            modules/
                            vpc/
                            security_group/
                            ecs_service/
                            rds_postgres/
                            iam_role/
                            dns_record/
What modules should achieve
Module qualityProfessional expectation
ReusableInputs and outputs are clear and minimal.
SafeDefault values do not expose public access unintentionally.
ReadableVariables, tags, and naming conventions are consistent.
ComposableModules can be combined into complete environments.
Remote state and locking
Terraform code
                            │
                            ▼
                            Backend configuration
                            │
                            ├── remote state storage
                            ├── state version history
                            └── state lock
                            │
                            ▼
                            Plan / Apply
                            │
                            ▼
                            State updated safely
State topicBest practice
LocationUse remote storage, not a local laptop file.
LockingPrevent concurrent apply operations.
AccessRestrict who can read or modify the state.
SensitivityAssume state may expose sensitive values; protect it accordingly.
Example production use case

A team builds a three-tier web platform on AWS. Terraform modules provision the VPC, NAT gateways, ALB, ECS services, RDS, IAM roles, Route53 records, and alarms. The GitLab pipeline runs fmt, validate, security checks, plan, then an approval gate, then apply only on protected branches.

GitLab CI/CD for infrastructure
Standard infra pipeline
Stages
                            1. lint
                            2. validate
                            3. security_scan
                            4. plan
                            5. review / approval
                            6. apply
                            7. post_deploy_checks
StageGoal
lintFormat and style consistency.
validateCatch syntax and structural errors early.
security_scanDetect risky Terraform patterns and policy violations.
planShow intended infrastructure changes before apply.
approvalHuman control point for sensitive environments.
applyExecute only in controlled, protected contexts.
post_deploy_checksVerify service health, alarms, and smoke tests.
Critical CI/CD controls
ControlWhy it matters
Protected branchesPrevent direct, unreviewed production changes.
Protected variablesKeep secrets out of untrusted branches.
Scoped runnersReduce blast radius and credential exposure.
Manual apply in productionProvide an explicit checkpoint.
ArtifactsPreserve plan output and audit trail.
Professional CI/CD rule

A pipeline is not only an execution engine. It is an enforcement layer for review, quality checks, security rules, approvals, and production traceability.

Do not do this: allow every developer to run production apply directly from local machines.
Incident handling: what “professional” looks like
SEV-1 incident flow
Alert fires
                            │
                            ▼
                            Triage
                            │
                            ├── confirm impact
                            ├── identify affected scope
                            └── assign incident lead
                            │
                            ▼
                            Mitigation
                            ├── rollback
                            ├── disable bad change
                            ├── failover
                            └── traffic control
                            │
                            ▼
                            Recovery validation
                            ├── health checks
                            ├── logs
                            ├── metrics
                            └── business KPI
                            │
                            ▼
                            Postmortem
                            ├── timeline
                            ├── root cause
                            ├── corrective actions
                            └── prevention
Example incident in production
Security group update breaks database connectivity
  1. Alert shows API error rate spike and DB connection failures.
  2. On-call verifies a recent infrastructure change.
  3. Terraform plan/apply history identifies a modified security group rule.
  4. Immediate mitigation: revert or restore DB access rule.
  5. Confirm service health via application metrics and database checks.
  6. Write postmortem: why review missed it, what test/guardrail is needed.
Incident response roles
RoleResponsibility
Incident leadCoordinates technical response and decisions.
Communications leadUpdates stakeholders and customer-facing channels.
Operations engineerExecutes rollback, checks infra, validates mitigation.
Application engineerCorrelates infra changes with app behavior.
Postmortem quality checklist
  • Precise timeline with timestamps.
  • Customer impact and internal impact.
  • Triggering change or trigger event.
  • Root cause, not only the symptom.
  • What worked well during response.
  • Corrective actions with owners and deadlines.
Professional reflex: restore service first, then investigate deeply.
How DevOps expectations differ by company type
Company typeTypical DevOps focusExamples of concern
Startup SaaSSpeed, automation, cost awareness, fast recovery.Simple platform, small team, high pressure to deliver.
E-commerceTraffic peaks, latency, checkout reliability, on-call maturity.Black Friday readiness, scaling, payment path resilience.
Fintech / bankingSecurity, compliance, approval workflows, audit trail.Separation of duties, secrets management, restricted access.
Industrial / enterprise ITStability, change control, hybrid systems, documentation.Legacy integration, strict release windows.
Media / streamingScalability, CDN, real-time monitoring, resilience.Traffic spikes, regional performance, caching strategy.
Example 1: SaaS company

In a SaaS company, DevOps is often expected to own cloud provisioning, CI/CD, observability, and incident response. The emphasis is on velocity, but velocity must be constrained by good delivery controls.

Example 2: Fintech company

In a fintech environment, infrastructure changes may require formal approvals, stronger audit trails, tighter IAM policies, and detailed rollback procedures. The same Terraform skillset applies, but the governance layer is much stricter.

Example 3: E-commerce company

Here, DevOps often focuses on availability, latency, autoscaling, traffic peaks, logging, and fast rollback capability. Promotion periods require readiness plans, dashboards, and clear incident escalation.

Interview tip: when speaking about DevOps experience, adapt your answer to the company’s business model: speed for SaaS, resilience for e-commerce, control and compliance for fintech.
Operational KPI, SLA, SLO, and reliability signals
MetricWhat it tells you
AvailabilityPercentage of time the service is reachable and working.
Error rateHow many requests fail over time.
Latency p95 / p99User-perceived speed under load.
MTTDMean time to detect an issue.
MTTRMean time to recover service.
Deployment frequencyHow often the team ships safely.
Change failure rateHow often releases or changes introduce incidents.
SLA / SLO / Error budget
ConceptMeaning
SLAExternal commitment to customers, often contractual.
SLOInternal target for reliability or performance.
SLIMeasured indicator used to evaluate the SLO.
Error budgetAllowed unreliability before delivery must slow down.
Example

A service may have an internal SLO of 99.9% availability. If incidents consume too much of the error budget, the team should pause risky changes and focus on stability improvements.

Top anti-patterns to avoid
Anti-patternWhy it is dangerousProfessional alternative
ClickOps onlyManual changes create drift and no audit trail.Put infra in Terraform and review all changes.
Local state on laptopsLost state and conflicting applies become likely.Use protected remote state with locking.
Production apply from any branchHigh blast radius and poor control.Use protected branches, approvals, and environment gates.
No monitoring before go-liveIssues are discovered too late.Create dashboards and alerts before release.
No rollback planRecovery becomes slow and chaotic.Define mitigation and rollback before deployment.
Too much access in CI runnersSecrets and production scope are exposed.Use least privilege and scope per environment.
Huge changesetsHard to review and harder to recover from.Prefer small, frequent, well-documented changes.
Professional DevOps maturity: not “more tools”, but better controls, clearer recovery paths, stronger observability, and cleaner operational discipline.
1.2 Terraform : bases solides en production
Terraform : ce qu’il faut vraiment comprendre

Terraform est un outil d’Infrastructure as Code. Il permet de décrire l’état attendu d’une infrastructure dans des fichiers versionnés, puis de comparer cet état avec la réalité du cloud ou du provider ciblé.

Contrairement à un script Bash classique, Terraform ne se contente pas d’exécuter des commandes dans l’ordre. Il construit un graphe de dépendances, calcule les différences entre le code et l’état réel, puis propose un plan d’action.

Phrase clé : Terraform ne décrit pas “comment cliquer dans la console”, il décrit “quel état d’infrastructure doit exister”.
Exemples d’objets gérés
FamilleExemples concrets
RéseauVPC, subnets, route tables, NAT gateway, firewall rules.
ComputeVM, autoscaling group, ECS service, Kubernetes node pool.
SécuritéIAM roles, policies, security groups, KMS keys.
DonnéesRDS PostgreSQL, MySQL, Redis, buckets S3, volumes.
RoutageDNS, load balancer, listeners, certificats TLS.
ObservabilitéAlarmes CloudWatch, dashboards, log groups, alert rules.
Lexique essentiel
TermeRôle
ProviderConnecteur vers AWS, Azure, GCP, GitLab, Cloudflare, Hetzner, Kubernetes, etc.
ResourceObjet que Terraform crée, modifie ou supprime.
Data sourceObjet existant que Terraform lit sans forcément le gérer.
VariableParamètre d’entrée permettant d’adapter le code à chaque environnement.
OutputValeur exposée après exécution : IP, DNS, ARN, endpoint, ID.
StateMémoire Terraform reliant le code aux ressources réellement créées.
PlanDiff calculé avant modification réelle de l’infrastructure.
ApplyApplication effective des changements proposés par le plan.
Diagramme mental
Code Terraform
                            │
                            ├── providers
                            ├── variables
                            ├── resources
                            ├── data sources
                            └── outputs
                            │
                            ▼
                            terraform plan
                            │
                            ▼
                            Diff entre état souhaité et état réel
                            │
                            ▼
                            terraform apply
                            │
                            ▼
                            Infrastructure créée / modifiée / supprimée
                            │
                            ▼
                            State Terraform mis à jour
Vision professionnelle : Terraform devient critique dès que plusieurs personnes, plusieurs environnements ou plusieurs clouds doivent être gérés proprement.
Architecture Terraform professionnelle

Un projet Terraform sérieux doit être organisé pour éviter le chaos : séparation des environnements, modules réutilisables, backend distant, conventions de nommage, tagging, sécurité et validation CI/CD.

Architecture recommandée
infra/
                            ├── modules/
                            │   ├── network/
                            │   │   ├── main.tf
                            │   │   ├── variables.tf
                            │   │   ├── outputs.tf
                            │   │   └── README.md
                            │   ├── security_group/
                            │   ├── compute_service/
                            │   ├── database/
                            │   ├── dns/
                            │   └── monitoring/
                            │
                            ├── live/
                            │   ├── dev/
                            │   │   ├── network/
                            │   │   ├── app/
                            │   │   └── data/
                            │   ├── staging/
                            │   │   ├── network/
                            │   │   ├── app/
                            │   │   └── data/
                            │   └── prod/
                            │       ├── network/
                            │       ├── app/
                            │       └── data/
                            │
                            └── global/
                            ├── iam/
                            ├── dns/
                            └── shared-services/
Bonne pratique : ne pas mettre toute la production dans un seul énorme dossier Terraform. Il faut découper par domaine : réseau, sécurité, application, données, observabilité.
Découpage par domaine
DomaineContenu typiqueRisque principal
networkVPC, subnets, routes, NAT, peering.Couper tout le trafic si erreur.
securityIAM, security groups, KMS, firewall.Ouvrir trop large ou bloquer la prod.
appCompute, containers, load balancer, autoscaling.Indisponibilité applicative.
dataRDS, Redis, buckets, volumes.Perte de données ou recréation accidentelle.
monitoringAlarmes, dashboards, logs.Incident invisible ou alertes inutiles.
Diagramme d’organisation
modules/
                            │
                            ├── composants réutilisables
                            │
                            ▼
                            live/dev
                            live/staging
                            live/prod
                            │
                            ├── appellent les modules
                            ├── passent les variables
                            ├── utilisent un backend state dédié
                            └── exposent les outputs utiles
Erreur fréquente : copier-coller des blocs Terraform entre environnements au lieu de créer des modules propres et paramétrables.
Fichiers Terraform : rôle et structure
Structure minimale propre
terraform/
                            ├── providers.tf
                            ├── versions.tf
                            ├── backend.tf
                            ├── variables.tf
                            ├── main.tf
                            ├── outputs.tf
                            ├── locals.tf
                            ├── terraform.tfvars
                            └── README.md
FichierRôle
versions.tfContraintes de versions Terraform et providers.
providers.tfConfiguration des providers : AWS, Azure, GitLab, etc.
backend.tfConfiguration du stockage distant du state.
variables.tfDéclaration des paramètres d’entrée.
main.tfRessources principales ou appel aux modules.
locals.tfValeurs calculées, conventions de nommage, tags communs.
outputs.tfValeurs exposées après création.
terraform.tfvarsValeurs concrètes pour un environnement donné.
Exemple : versions.tf
terraform {
                            required_version = ">= 1.6.0"

                            required_providers {
                            aws = {
                            source  = "hashicorp/aws"
                            version = "~> 5.0"
                            }
                            }
                            }
Exemple : providers.tf
provider "aws" {
                            region = var.aws_region

                            default_tags {
                            tags = local.common_tags
                            }
                            }
Exemple : locals.tf
locals {
                            name_prefix = "${var.project}-${var.environment}"

                            common_tags = {
                            Project     = var.project
                            Environment = var.environment
                            ManagedBy   = "terraform"
                            Owner       = var.owner
                            }
                            }
Astuce pro : les tags standards sont indispensables en production pour la facturation, l’audit, la sécurité, l’inventaire et le support.
Providers : la passerelle vers les plateformes

Un provider est le connecteur qui permet à Terraform de discuter avec une API externe : AWS, Azure, GCP, GitLab, Cloudflare, Kubernetes, Datadog, Vault, Hetzner, etc.

Providers fréquents en production
ProviderUsage courant
AWSVPC, EC2, ECS, EKS, RDS, IAM, S3, CloudWatch, Route53.
AzureResource groups, VNets, AKS, Key Vault, SQL, App Services.
Google CloudVPC, GKE, Cloud SQL, IAM, Cloud Storage, Cloud Run.
KubernetesNamespaces, secrets, config maps, services, deployments.
GitLabProjects, variables CI/CD, runners, groups, access tokens.
CloudflareDNS, WAF, CDN, firewall rules.
DatadogDashboards, monitors, alerting, SLO.
Point important : Terraform peut gérer bien plus que le cloud : il peut aussi piloter GitLab, DNS, monitoring, sécurité, secrets et plateformes internes.
Exemple multi-provider
provider "aws" {
                            region = var.aws_region
                            }

                            provider "cloudflare" {
                            api_token = var.cloudflare_api_token
                            }

                            provider "gitlab" {
                            token = var.gitlab_token
                            }
Risques liés aux providers
RisquePrévention
Version non maîtriséeFixer les versions dans required_providers.
Credentials trop largesUtiliser des droits limités par environnement.
Provider upgrade cassantTester en dev/staging avant production.
API rate limitÉviter les plans énormes et surveiller les quotas.
Bon réflexe professionnel
Avant upgrade provider
                            │
                            ├── lire changelog
                            ├── lancer terraform init -upgrade en dev
                            ├── vérifier terraform plan
                            ├── tester en staging
                            └── appliquer en prod uniquement après validation
Resources et data sources
Resource : Terraform gère l’objet

Une resource représente un objet que Terraform doit créer, modifier ou supprimer. Exemple : une instance, un bucket, une règle réseau, une base de données.

resource "aws_security_group" "web" {
                            name        = "${local.name_prefix}-web-sg"
                            description = "Security group for web traffic"
                            vpc_id      = var.vpc_id

                            ingress {
                            description = "HTTPS from internet"
                            from_port   = 443
                            to_port     = 443
                            protocol    = "tcp"
                            cidr_blocks = ["0.0.0.0/0"]
                            }

                            egress {
                            description = "Outbound traffic"
                            from_port   = 0
                            to_port     = 0
                            protocol    = "-1"
                            cidr_blocks = ["0.0.0.0/0"]
                            }
                            }
Attention : ouvrir 0.0.0.0/0 est acceptable pour HTTPS public, mais dangereux pour SSH, bases de données, Redis, Elasticsearch ou interfaces admin.
Data source : Terraform lit l’existant

Une data source permet de récupérer une information existante sans en devenir propriétaire. C’est utile pour référencer une AMI, un VPC existant, un secret, une zone DNS, etc.

data "aws_ami" "ubuntu" {
                            most_recent = true
                            owners      = ["099720109477"]

                            filter {
                            name   = "name"
                            values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
                            }
                            }
Resource vs Data source
ÉlémentTerraform est propriétaire ?Exemple
ResourceOuiCréer un security group.
Data sourceNonLire une AMI Ubuntu existante.
Cycle de dépendances
data source
                            │
                            ▼
                            récupère une information existante
                            │
                            ▼
                            resource
                            │
                            ▼
                            utilise cette information pour créer un objet
Variables, outputs et conventions
Variables d’entrée

Les variables permettent de rendre le code Terraform paramétrable. Elles évitent de dupliquer le même code pour dev, staging et production.

variable "project" {
                            description = "Project name"
                            type        = string
                            }

                            variable "environment" {
                            description = "Deployment environment"
                            type        = string

                            validation {
                            condition     = contains(["dev", "staging", "prod"], var.environment)
                            error_message = "Environment must be dev, staging, or prod."
                            }
                            }

                            variable "instance_type" {
                            description = "EC2 instance type"
                            type        = string
                            default     = "t3.micro"
                            }
Exemple terraform.tfvars
project       = "ideo-platform"
                            environment   = "prod"
                            aws_region    = "eu-west-3"
                            owner         = "platform-team"
                            instance_type = "t3.medium"
Bonne pratique : typer les variables et ajouter des validations quand une erreur de saisie peut provoquer un incident.
Outputs utiles

Les outputs exposent des valeurs générées par Terraform : endpoint de base de données, DNS du load balancer, ID du VPC, ARN d’un rôle IAM, etc.

output "load_balancer_dns_name" {
                            description = "Public DNS name of the load balancer"
                            value       = aws_lb.main.dns_name
                            }

                            output "security_group_id" {
                            description = "Web security group ID"
                            value       = aws_security_group.web.id
                            }
Variables sensibles
variable "database_password" {
                            description = "Database password"
                            type        = string
                            sensitive   = true
                            }
Type de donnéeConseil
Mot de passeNe pas mettre en clair dans Git.
Token APIUtiliser variables CI/CD protégées ou secret manager.
Clé privéeÉviter dans Terraform si possible.
Endpoint publicOutput acceptable si non sensible.
Attention : sensitive = true masque l’affichage CLI, mais ne garantit pas que la valeur soit absente du state.
Cycle Terraform : init, fmt, validate, plan, apply
Cycle standard
terraform init
                            terraform fmt -check -recursive
                            terraform validate
                            terraform plan -var-file="prod.tfvars" -out="tfplan"
                            terraform apply "tfplan"
Rôle de chaque commande
CommandeRôle
terraform initInitialise le backend, télécharge les providers et modules.
terraform fmtFormate le code selon les conventions Terraform.
terraform validateVérifie la cohérence syntaxique et structurelle.
terraform planAffiche ce qui va changer sans modifier l’infrastructure.
terraform applyApplique réellement les changements.
terraform destroyDétruit les ressources gérées. À éviter en production sauf cas maîtrisé.
Lire un plan Terraform
SymboleSignificationNiveau de risque
+Création d’une ressource.Normal, mais à vérifier.
~Modification en place.Moyen selon la ressource.
-/+Destruction puis recréation.Élevé, surtout sur data / réseau.
-Suppression.Très élevé en production.
Diagramme du cycle
Code modifié
                            │
                            ▼
                            terraform fmt
                            │
                            ▼
                            terraform validate
                            │
                            ▼
                            terraform plan
                            │
                            ├── aucun changement : OK
                            ├── création : vérifier nommage / tags / coût
                            ├── modification : vérifier impact
                            └── destruction : analyse obligatoire
                            │
                            ▼
                            review humaine
                            │
                            ▼
                            terraform apply
                            │
                            ▼
                            contrôles post-apply
Règle production : toute destruction ou recréation doit être explicitement comprise avant validation du apply.
State Terraform : le point le plus critique

Le state est la mémoire de Terraform. Il contient la correspondance entre les ressources déclarées dans le code et les ressources réellement créées chez le provider. Sans state fiable, Terraform ne sait plus correctement ce qu’il possède.

Pourquoi le state est sensible
SujetRisqueBonne pratique
State localPerte, divergence, conflit entre développeurs.Utiliser un backend distant.
ConcurrenceDeux apply en même temps peuvent corrompre l’état.Activer le verrouillage du state.
SensibilitéLe state peut contenir des valeurs sensibles.Restreindre les accès et chiffrer.
SuppressionTerraform perd la mémoire de l’infra gérée.Versionner et protéger le backend.
Exemple backend S3
terraform {
                            backend "s3" {
                            bucket         = "company-terraform-state-prod"
                            key            = "prod/network/terraform.tfstate"
                            region         = "eu-west-3"
                            dynamodb_table = "terraform-locks"
                            encrypt        = true
                            }
                            }
Important : le bucket de state doit lui-même être protégé, versionné, chiffré et limité en accès.
State locking
Pipeline A lance terraform apply
                            │
                            ▼
                            verrouillage du state
                            │
                            ├── Pipeline A peut écrire
                            └── Pipeline B doit attendre
                            │
                            ▼
                            fin du apply
                            │
                            ▼
                            déverrouillage du state
Commandes liées au state
CommandeUsage
terraform state listLister les ressources connues du state.
terraform state showInspecter une ressource du state.
terraform importRattacher une ressource existante au state.
terraform state rmRetirer une ressource du state sans la supprimer réellement.
terraform state mvDéplacer ou renommer une ressource dans le state.
À éviter : manipuler le state à la main sans sauvegarde, sans revue et sans comprendre l’impact exact.
Terraform en production : cas concret
Exemple : plateforme web sur AWS
Route53 / DNS
                            │
                            ▼
                            Application Load Balancer
                            │
                            ▼
                            ECS / EC2 / Kubernetes
                            │
                            ├── service web
                            ├── workers
                            └── autoscaling
                            │
                            ▼
                            RDS PostgreSQL
                            │
                            ├── backups
                            ├── monitoring
                            └── security groups
                            │
                            ▼
                            CloudWatch / Grafana / Alerting
Ce que Terraform peut gérer
ComposantTerraform gère
RéseauVPC, subnets privés/publics, NAT, routes.
SécuritéSecurity groups, IAM roles, policies.
ApplicationLoad balancer, target groups, compute, autoscaling.
DatabaseInstance RDS, subnet group, backup window, monitoring.
DNSRecords Route53, certificats, validation DNS.
ObservabilitéAlarmes CPU, mémoire, 5xx, latence, logs.
Processus professionnel de changement
Besoin métier
                            │
                            ▼
                            ticket ou demande de changement
                            │
                            ▼
                            branche Git
                            │
                            ▼
                            modification Terraform
                            │
                            ▼
                            merge request
                            │
                            ├── fmt
                            ├── validate
                            ├── security scan
                            └── plan
                            │
                            ▼
                            review du plan
                            │
                            ▼
                            approval production
                            │
                            ▼
                            apply contrôlé
                            │
                            ▼
                            vérifications post-changement
                            │
                            ├── logs
                            ├── métriques
                            ├── health checks
                            └── coût / sécurité
Contrôles indispensables
ContrôlePourquoi
Plan reluÉviter suppression ou recréation involontaire.
State verrouilléEmpêcher deux apply concurrents.
Variables protégéesLimiter l’exposition des credentials.
Rollback ou mitigationRétablir vite en cas d’incident.
Monitoring actifVoir rapidement si le changement dégrade la production.
Niveau pro : Terraform ne doit jamais être utilisé comme un simple outil local. En production, il doit être intégré dans Git, CI/CD, monitoring et processus de changement.
Erreurs courantes et réflexes professionnels
ErreurCause probableRisqueRéflexe professionnel
Provider conflictVersions non figées ou incompatibles.Plan instable ou comportement imprévu.Fixer les versions dans required_providers.
State lockUn autre job Terraform utilise le state.Apply concurrent ou state corrompu.Identifier le job actif, attendre, ne pas forcer sans analyse.
DriftModification manuelle dans la console cloud.Terraform veut annuler ou recréer des ressources.Comparer, importer, corriger le code ou revenir à l’état attendu.
Permission deniedCredentials CI/CD insuffisants ou mal scopés.Pipeline bloqué ou changement partiel.Contrôler IAM, scopes, variables protégées, rôle du runner.
Resource already existsObjet déjà créé hors Terraform.Duplication impossible ou conflit de nom.Utiliser terraform import ou renommer proprement.
Plan wants to destroyChangement de nom, clé, module, lifecycle ou dépendance.Suppression de ressource critique.Analyser le diff, utiliser lifecycle, state mv si nécessaire.
Invalid index / null valueVariable absente, liste vide, condition mal gérée.Pipeline cassé.Ajouter validation, valeurs par défaut, conditions robustes.
Exemple : destruction involontaire
Modification du nom logique d'une resource
                            │
                            ▼
                            Terraform croit que l'ancienne resource doit disparaître
                            │
                            ▼
                            Plan affiche -/+ ou destroy
                            │
                            ▼
                            Danger : recréation ou perte de service
                            │
                            ▼
                            Solution possible :
                            ├── terraform state mv
                            ├── lifecycle prevent_destroy
                            └── revue du plan avant apply
Lifecycle utile
resource "aws_db_instance" "main" {
                            identifier = "${local.name_prefix}-db"

                            lifecycle {
                            prevent_destroy = true
                            }
                            }
Attention : prevent_destroy est une ceinture de sécurité, pas une excuse pour ne pas relire le plan.
Checklist professionnelle Terraform
Avant merge request
PointValidation
Formatterraform fmt -check -recursive passe correctement.
Validationterraform validate ne remonte pas d’erreur.
VariablesTypes, descriptions et validations définis.
TagsProject, Environment, Owner, ManagedBy présents.
SécuritéPas de secret en clair, pas d’ouverture réseau dangereuse.
ModulesInputs/outputs lisibles, README si module partagé.
Avant apply production
PointQuestion à poser
PlanLe plan a-t-il été relu par une autre personne ?
DestroyY a-t-il une suppression ou recréation ? Si oui, pourquoi ?
StateLe state est-il distant, verrouillé et protégé ?
RollbackExiste-t-il une procédure de mitigation si problème ?
MonitoringLes métriques et logs permettront-ils de voir l’impact ?
FenêtreLe changement est-il fait au bon moment opérationnel ?
Objectif final : un changement Terraform doit être lisible, prévisible, auditable, réversible ou au minimum mitigable.
Mini-cheat-sheet
terraform init
                    terraform fmt -recursive
                    terraform validate
                    terraform plan -var-file="dev.tfvars"
                    terraform apply -var-file="dev.tfvars"
                    terraform state list
                    terraform state show RESOURCE_NAME
                    terraform import RESOURCE_NAME PROVIDER_ID
                    terraform output
1.3 Modules Terraform : découpage réutilisable et production-ready
Pourquoi créer des modules Terraform ?

Un module Terraform est une brique d’infrastructure réutilisable. Il encapsule une responsabilité claire : réseau, sécurité, compute, base de données, DNS, monitoring, load balancer, IAM ou applicatif.

Sans modules, un projet Terraform finit souvent en copier-coller massif entre dev, staging et production. Cela crée des divergences, des erreurs de configuration, des plans difficiles à relire et une maintenance fragile.

Objectif professionnel : créer des composants standardisés, testables, documentés et réutilisables par plusieurs environnements ou plusieurs équipes.
Ce qu’un module doit apporter
ObjectifImpact concret
RéutilisationLe même module peut servir pour dev, staging, prod ou plusieurs projets.
LisibilitéLe root module reste compréhensible : il appelle des briques métier.
StandardisationNommage, tags, sécurité, logs et conventions sont homogènes.
ContrôleLes variables exposées limitent ce que l’utilisateur du module peut modifier.
MaintenanceUne correction dans le module peut bénéficier à plusieurs environnements.
AuditLes décisions d’infrastructure deviennent plus faciles à relire et expliquer.
Découpage logique d’une plateforme
Root module d'un environnement
                            │
                            ├── module.network
                            │     ├── VPC
                            │     ├── subnets publics / privés
                            │     ├── routes
                            │     └── NAT gateway
                            │
                            ├── module.security
                            │     ├── security groups
                            │     ├── IAM roles
                            │     ├── policies
                            │     └── KMS
                            │
                            ├── module.compute
                            │     ├── VM / ECS / EKS
                            │     ├── autoscaling
                            │     ├── load balancer
                            │     └── health checks
                            │
                            ├── module.database
                            │     ├── PostgreSQL / MariaDB
                            │     ├── subnet group
                            │     ├── backups
                            │     └── monitoring
                            │
                            └── module.observability
                            ├── logs
                            ├── metrics
                            ├── alarms
                            └── dashboards
Module vs simple fichier Terraform
ApprocheUsage adaptéLimite
Fichier simplePetit prototype, test local, ressource isolée.Devient vite illisible en production.
Module localProjet structuré avec plusieurs domaines.Versioning moins fort si tout est dans le même repo.
Module versionnéStandard d’entreprise partagé par plusieurs équipes.Nécessite gouvernance, releases et compatibilité.
Vision pro : un module n’est pas seulement du code factorisé. C’est un contrat d’infrastructure stable entre l’équipe plateforme et les consommateurs.
Architecture recommandée pour modules Terraform

Un bon découpage sépare les modules réutilisables du code live qui instancie ces modules pour un environnement précis.

Arborescence professionnelle
infra/
                            ├── modules/
                            │   ├── network/
                            │   │   ├── main.tf
                            │   │   ├── variables.tf
                            │   │   ├── outputs.tf
                            │   │   ├── locals.tf
                            │   │   ├── versions.tf
                            │   │   └── README.md
                            │   │
                            │   ├── security-group/
                            │   ├── load-balancer/
                            │   ├── compute-service/
                            │   ├── database-postgres/
                            │   ├── redis-cache/
                            │   ├── dns-record/
                            │   └── monitoring-alarm/
                            │
                            ├── live/
                            │   ├── dev/
                            │   │   ├── network/
                            │   │   ├── app/
                            │   │   └── data/
                            │   ├── staging/
                            │   │   ├── network/
                            │   │   ├── app/
                            │   │   └── data/
                            │   └── prod/
                            │       ├── network/
                            │       ├── app/
                            │       └── data/
                            │
                            └── global/
                            ├── iam/
                            ├── dns/
                            └── shared-services/
Bonne pratique : les modules décrivent des briques génériques. Les dossiers live décrivent les environnements réels.
Root module vs child module
TypeRôleExemple
Root modulePoint d’entrée exécuté par terraform plan/apply.live/prod/app/
Child moduleBrique appelée par le root module.modules/load-balancer
Shared moduleModule partagé entre plusieurs repos ou équipes.git::ssh://...
External moduleModule public ou privé publié dans un registry.Terraform Registry, GitLab module registry.
Flux d’instanciation
live/prod/app
                            │
                            ├── définit les variables prod
                            ├── configure le backend state prod
                            ├── appelle les modules nécessaires
                            └── expose les outputs utiles
                            │
                            ▼
                            modules/
                            ├── network
                            ├── security
                            ├── compute
                            └── database
Exemple d’appel module
module "web_service" {
                            source = "../../modules/compute-service"

                            project       = var.project
                            environment   = var.environment
                            vpc_id        = module.network.vpc_id
                            subnet_ids    = module.network.private_subnet_ids
                            instance_type = var.web_instance_type

                            tags = local.common_tags
                            }
Le contrat d’un module : inputs, outputs, garanties

Un module Terraform sérieux doit être pensé comme une API. Il expose des inputs, retourne des outputs, applique des conventions et documente clairement ce qu’il crée.

Inputs : variables propres et typées
variable "project" {
                            description = "Project name used for naming and tags."
                            type        = string
                            }

                            variable "environment" {
                            description = "Environment name."
                            type        = string

                            validation {
                            condition     = contains(["dev", "staging", "prod"], var.environment)
                            error_message = "Environment must be dev, staging, or prod."
                            }
                            }

                            variable "subnet_ids" {
                            description = "Private subnet IDs used by the service."
                            type        = list(string)
                            }

                            variable "enable_public_access" {
                            description = "Whether the service is publicly exposed."
                            type        = bool
                            default     = false
                            }
Règle : toutes les variables doivent avoir un type, une description, et une validation quand le risque d’erreur est important.
Outputs : exposer seulement l’utile
output "service_name" {
                            description = "Name of the created service."
                            value       = aws_ecs_service.main.name
                            }

                            output "security_group_id" {
                            description = "Security group attached to the service."
                            value       = aws_security_group.service.id
                            }

                            output "load_balancer_dns_name" {
                            description = "Public DNS name of the load balancer."
                            value       = aws_lb.main.dns_name
                            }
Qualité du contrat
ÉlémentBonne pratique
InputsPeu nombreux, typés, documentés, avec defaults raisonnables.
OutputsLimités aux valeurs nécessaires aux autres modules ou à l’exploitation.
NommagePrévisible : projet, environnement, composant, région.
TagsAppliqués partout quand le provider le permet.
SécuritéPas d’accès public par défaut, pas de droits trop larges.
Attention : un module trop flexible devient dangereux. Il vaut mieux exposer quelques options sûres que toutes les options possibles.
Diagramme du contrat
Utilisateur du module
                    │
                    ├── fournit des inputs contrôlés
                    │
                    ▼
                    Module Terraform
                    │
                    ├── applique conventions
                    ├── crée ressources
                    ├── impose sécurité par défaut
                    └── produit outputs
                    │
                    ▼
                    Autres modules / exploitation / CI/CD
Exemple de module réseau

Le module réseau est souvent la base de toute infrastructure cloud. Il crée le VPC, les subnets, les routes, les gateways et expose les IDs nécessaires aux modules applicatifs.

Responsabilités du module network
ResponsabilitéDétail
VPC / réseau principalDéfinir le CIDR global de l’environnement.
Subnets publicsLoad balancers, NAT gateways, bastions éventuels.
Subnets privésApplications, workers, bases de données, caches.
RoutesAccès internet, NAT, peering, transit gateway.
OutputsVPC ID, subnet IDs, route table IDs, CIDR blocks.
Exemple d’appel
module "network" {
                            source = "../../modules/network"

                            project           = var.project
                            environment       = var.environment
                            vpc_cidr          = "10.20.0.0/16"
                            public_subnets    = ["10.20.1.0/24", "10.20.2.0/24"]
                            private_subnets   = ["10.20.11.0/24", "10.20.12.0/24"]
                            availability_zones = ["eu-west-3a", "eu-west-3b"]

                            tags = local.common_tags
                            }
Diagramme réseau type
VPC 10.20.0.0/16
                            │
                            ├── Public Subnet A
                            │     ├── Load Balancer
                            │     └── NAT Gateway
                            │
                            ├── Public Subnet B
                            │     ├── Load Balancer
                            │     └── NAT Gateway
                            │
                            ├── Private App Subnet A
                            │     └── Web / API / Workers
                            │
                            ├── Private App Subnet B
                            │     └── Web / API / Workers
                            │
                            └── Private Data Subnets
                            ├── PostgreSQL
                            ├── Redis
                            └── Search
Outputs réseau
output "vpc_id" {
                            value = aws_vpc.main.id
                            }

                            output "private_subnet_ids" {
                            value = aws_subnet.private[*].id
                            }

                            output "public_subnet_ids" {
                            value = aws_subnet.public[*].id
                            }
Risque production : une erreur dans le module réseau peut couper tout le trafic. Les changements réseau doivent être petits, relus et testés en staging.
Exemple de module compute / applicatif

Le module compute représente la couche qui exécute l’application : VM, autoscaling group, ECS service, EKS deployment, load balancer ou worker.

Responsabilités possibles
ComposantRôle
ComputeEC2, ECS service, EKS workload, instance group.
Load balancerEntrée HTTP/HTTPS, health checks, target groups.
AutoscalingAdapter la capacité selon CPU, mémoire, trafic.
LogsConfigurer log group, rétention, format.
MonitoringAlarmes 5xx, latence, CPU, mémoire, tâches unhealthy.
Exemple d’appel
module "api_service" {
                            source = "../../modules/compute-service"

                            project        = var.project
                            environment    = var.environment
                            vpc_id         = module.network.vpc_id
                            subnet_ids     = module.network.private_subnet_ids
                            image          = var.api_image
                            desired_count  = 3
                            min_capacity   = 2
                            max_capacity   = 8

                            enable_public_load_balancer = true
                            health_check_path           = "/health/"

                            tags = local.common_tags
                            }
Diagramme applicatif
Internet
                            │
                            ▼
                            Load Balancer
                            │
                            ├── health check /health/
                            │
                            ▼
                            Compute Service
                            ├── task / instance 1
                            ├── task / instance 2
                            └── task / instance 3
                            │
                            ├── logs
                            ├── metrics
                            └── autoscaling policy
                            │
                            ▼
                            Database / Cache / APIs internes
Outputs utiles
output "service_name" {
                            value = aws_ecs_service.main.name
                            }

                            output "load_balancer_dns_name" {
                            value = aws_lb.main.dns_name
                            }

                            output "service_security_group_id" {
                            value = aws_security_group.service.id
                            }
Bonne pratique : un module compute doit intégrer les health checks, les logs et les métriques dès le départ, pas après le premier incident.
Exemple de module database

Les modules database sont les plus sensibles : ils gèrent des ressources avec état, des sauvegardes, des secrets, des fenêtres de maintenance et parfois des contraintes fortes de disponibilité.

Paramètres essentiels
ParamètrePourquoi c’est important
engine / versionPostgreSQL, MySQL, MariaDB et version exacte.
instance classDimensionnement CPU/RAM.
storageCapacité, type disque, autoscaling éventuel.
backup retentionDurée de conservation des sauvegardes.
multi_azRésilience en cas de panne de zone.
deletion protectionProtection contre suppression accidentelle.
maintenance windowContrôle du moment des opérations sensibles.
Exemple d’appel
module "postgres" {
                            source = "../../modules/database-postgres"

                            project               = var.project
                            environment           = var.environment
                            subnet_ids            = module.network.private_subnet_ids
                            allowed_sg_ids        = [module.api_service.service_security_group_id]

                            engine_version        = "15"
                            instance_class        = "db.t3.medium"
                            allocated_storage_gb  = 100
                            backup_retention_days = 14
                            multi_az              = true
                            deletion_protection   = true

                            tags = local.common_tags
                            }
Diagramme database sécurisé
Application Security Group
                            │
                            ▼
                            Database Security Group
                            │
                            ├── autorise seulement le port DB
                            ├── refuse accès public
                            └── limite aux subnets privés
                            │
                            ▼
                            Managed Database
                            ├── backups automatiques
                            ├── monitoring
                            ├── maintenance window
                            ├── encryption
                            └── deletion protection
Protections recommandées
ProtectionBut
deletion_protectionEmpêcher suppression accidentelle.
prevent_destroyBloquer destruction Terraform non voulue.
backupsPermettre restauration après incident.
private subnetsÉviter exposition Internet.
restricted security groupLimiter les clients autorisés.
Règle absolue : un module database de production ne doit jamais être public par défaut et ne doit jamais être destructible facilement.
Sécurité des modules Terraform

Les modules imposent des standards. Ils doivent donc intégrer la sécurité par défaut : accès minimal, chiffrement, absence de secrets en clair, tags d’audit et garde-fous.

Règles de sécurité module
RègleExigence
Least privilegeNe pas créer des IAM policies trop larges par défaut.
No public by defaultUn module ne doit pas exposer Internet sauf choix explicite.
EncryptionActiver chiffrement pour stockage, logs et bases si disponible.
No hardcoded secretsPas de mot de passe, token ou clé dans le code Terraform.
Audit tagsTags Owner, Environment, ManagedBy, CostCenter si besoin.
Safe defaultsLes defaults doivent favoriser sécurité et stabilité.
Exemple validation sécurité
variable "allowed_cidr_blocks" {
                            description = "CIDR blocks allowed to access the service."
                            type        = list(string)
                            default     = []

                            validation {
                            condition     = length(var.allowed_cidr_blocks) > 0
                            error_message = "At least one allowed CIDR block must be provided."
                            }
                            }
Secrets : ce qu’il ne faut pas faire
# Mauvais exemple
                            variable "database_password" {
                            default = "SuperPassword123"
                            }
Approche préférable
variable "database_password" {
                            description = "Database password provided by CI/CD or secret manager."
                            type        = string
                            sensitive   = true
                            }
Outils liés à la sécurité
OutilUsage
CheckovAnalyse IaC pour mauvaises pratiques sécurité.
tfsecScan sécurité Terraform.
TrivyScan IaC, images containers et dépendances.
VaultGestion centralisée des secrets.
AWS Secrets ManagerSecrets managés côté AWS.
GitLab protected variablesInjection sécurisée en pipeline CI/CD.
Attention : marquer une variable sensitive masque l’affichage, mais ne remplace pas une vraie stratégie de secrets.
Versionner les modules Terraform

Dès qu’un module est utilisé par plusieurs environnements ou plusieurs équipes, il faut le versionner proprement. Sinon, une modification du module peut casser plusieurs stacks en même temps.

Source module : local vs Git
SourceUsageRisque
Local pathMonorepo, projet simple, modules internes.Pas de version explicite si même repo.
Git tagModule partagé et versionné.Nécessite release discipline.
RegistryStandard entreprise ou module public.Gouvernance et compatibilité requises.
Exemple module local
module "network" {
                            source = "../../modules/network"

                            project     = var.project
                            environment = var.environment
                            }
Exemple module Git versionné
module "network" {
                            source = "git::ssh://git@gitlab.com/company/terraform-modules.git//network?ref=v1.4.2"

                            project     = var.project
                            environment = var.environment
                            }
Stratégie de release module
Modification module
                            │
                            ▼
                            tests / terraform validate
                            │
                            ▼
                            merge request
                            │
                            ▼
                            release tag v1.4.2
                            │
                            ▼
                            environnement dev utilise v1.4.2
                            │
                            ▼
                            staging valide v1.4.2
                            │
                            ▼
                            production adopte v1.4.2
Compatibilité
Type de changementVersion conseillée
Correction interne sans changement d’APIPatch : v1.4.1 vers v1.4.2
Ajout d’option rétrocompatibleMinor : v1.4.2 vers v1.5.0
Suppression variable / changement breakingMajor : v1.x vers v2.0.0
Conseil pro : ne jamais faire pointer la production sur une branche mutable comme main. Utiliser des tags ou releases stables.
Modules Terraform et CI/CD

Les modules doivent être validés automatiquement. Une pipeline CI/CD peut contrôler le formatage, la syntaxe, les scans sécurité, les tests de plan et la documentation.

Pipeline de validation module
Commit module
                            │
                            ▼
                            terraform fmt -check
                            │
                            ▼
                            terraform validate
                            │
                            ▼
                            security scan
                            ├── checkov
                            ├── tfsec
                            └── trivy config
                            │
                            ▼
                            example plan
                            │
                            ▼
                            review humaine
                            │
                            ▼
                            tag de release
Exemple GitLab CI
stages:
                            - lint
                            - validate
                            - security

                            terraform_fmt:
                            stage: lint
                            script:
                            - terraform fmt -check -recursive

                            terraform_validate:
                            stage: validate
                            script:
                            - terraform init -backend=false
                            - terraform validate

                            checkov_scan:
                            stage: security
                            script:
                            - checkov -d .
                            allow_failure: false
Tests pratiques de module
TestBut
FormatCode homogène et lisible.
ValidateDétecter erreurs Terraform évidentes.
Security scanIdentifier ports ouverts, chiffrement manquant, IAM trop large.
Example planVérifier qu’un appel standard du module produit un plan cohérent.
Docs generationGénérer README variables / outputs avec terraform-docs.
Outils liés
OutilUtilité
terraform-docsGénère la documentation inputs / outputs.
tflintLint Terraform avancé.
CheckovPolicies sécurité IaC.
TerratestTests d’intégration Terraform en Go.
Niveau pro : un module partagé doit avoir des exemples, une documentation, des validations CI et une stratégie de release.
Anti-patterns des modules Terraform
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
Module géant uniqueImpossible à relire, à tester et à faire évoluer.Découper par responsabilité : network, compute, data, security.
Variables sans typeLes erreurs arrivent tard, souvent au plan ou à l’apply.Types explicites, validation, defaults sûrs.
Module trop flexibleChaque équipe peut créer une variante dangereuse.Exposer uniquement les options nécessaires et sûres.
Secrets dans tfvarsRisque de fuite Git, logs, artefacts CI/CD.Secret manager ou variables protégées CI/CD.
Outputs trop bavardsExposition d’informations internes ou sensibles.Outputs minimaux, sensitive = true si nécessaire.
Production sur branche mainUne modification module peut impacter prod sans contrôle de version.Utiliser tags ou releases versionnées.
Pas de READMELe module devient incompréhensible pour les nouveaux DevOps.Documenter usage, inputs, outputs, exemples et limitations.
Pas de garde-fou destructionRisque de supprimer database, bucket ou ressource critique.Utiliser prevent_destroy, protections provider, revue plan.
Mauvais module
module "everything"
                            ├── crée réseau
                            ├── crée IAM
                            ├── crée compute
                            ├── crée DB
                            ├── crée DNS
                            ├── crée monitoring
                            └── expose 80 variables
Problème : tout est couplé. Une petite modification peut avoir un impact impossible à prévoir.
Bon découpage
module.network
                            module.security
                            module.compute
                            module.database
                            module.dns
                            module.monitoring

                            Chaque module :
                            ├── responsabilité claire
                            ├── inputs contrôlés
                            ├── outputs utiles
                            └── documentation dédiée
Résultat : plans plus lisibles, changements plus sûrs, responsabilités mieux séparées.
Checklist de qualité d’un module Terraform
Checklist technique
PointValidation attendue
Responsabilité uniqueLe module fait une chose claire : réseau, compute, database, etc.
Variables typéesToutes les variables ont un type explicite.
DescriptionsInputs et outputs sont documentés.
ValidationsLes valeurs risquées sont contrôlées.
Defaults sûrsAucun accès public ou droit large par défaut.
TagsTags standards appliqués partout où possible.
Outputs minimauxLe module expose uniquement ce qui est nécessaire.
READMEUsage, exemples, variables, outputs, limites.
Checklist production
PointQuestion à poser
DestructionLe module peut-il supprimer une ressource critique ?
RéseauExpose-t-il quelque chose sur Internet par défaut ?
IAMCrée-t-il des permissions trop larges ?
SecretsUn secret peut-il finir dans Git, logs ou state ?
StateLe module est-il découpé pour éviter un state énorme ?
MonitoringLe module crée-t-il les logs/alarms nécessaires ?
VersioningLa production consomme-t-elle une version stable ?
RollbackExiste-t-il une stratégie en cas de mauvais changement ?
Définition d’un bon module : simple à appeler, difficile à mal utiliser, clair à relire, sécurisé par défaut et stable dans le temps.
Mini-cheat-sheet modules
# Appel d'un module local
                    module "network" {
                    source = "../../modules/network"

                    project     = var.project
                    environment = var.environment
                    tags        = local.common_tags
                    }

                    # Appel d'un module Git versionné
                    module "database" {
                    source = "git::ssh://git@gitlab.com/company/terraform-modules.git//database-postgres?ref=v1.2.0"

                    project     = var.project
                    environment = var.environment
                    }

                    # Générer la documentation
                    terraform-docs markdown table ./modules/network

                    # Valider un module
                    terraform fmt -check -recursive
                    terraform init -backend=false
                    terraform validate
1.4 State Terraform : backend, locking, drift et sécurité
Le state est la mémoire de Terraform

Le state Terraform est le fichier qui relie le code Terraform aux ressources réellement créées chez le provider. Il contient les IDs, attributs, dépendances, métadonnées et parfois certaines valeurs sensibles.

Sans state fiable, Terraform ne sait plus correctement ce qu’il possède. Il peut alors vouloir recréer, supprimer ou modifier des ressources de manière inattendue.

Point critique : le state n’est pas un simple fichier technique. C’est un actif de production qui doit être protégé comme une ressource sensible.
Ce que contient typiquement le state
ÉlémentExempleSensibilité
IDs providerID d’instance, ARN IAM, ID security group.Moyenne
Attributs ressourcesIP privée, endpoint DB, DNS load balancer.Moyenne à forte
DépendancesRelation entre réseau, compute et database.Faible à moyenne
Valeurs sensiblesMot de passe, token, secret selon provider/module.Forte
OutputsValeurs exposées par output.Variable
Le triangle Terraform
Code Terraform
                            │
                            │ décrit l'état souhaité
                            ▼
                            State Terraform
                            │
                            │ mémorise les objets gérés
                            ▼
                            Infrastructure réelle
                            │
                            │ AWS / Azure / GCP / GitLab / Kubernetes
                            ▼
                            terraform plan compare les 3 dimensions
Pourquoi le state est indispensable
BesoinRôle du state
Suivi des ressourcesSavoir quelles ressources appartiennent à Terraform.
Diff précisComparer l’état souhaité avec l’état connu.
Gestion des dépendancesComprendre l’ordre de création, modification ou destruction.
OutputsPartager certaines valeurs entre modules ou stacks.
CollaborationPermettre à une équipe de travailler sur la même infrastructure.
Vision pro : maîtriser Terraform sans comprendre le state est impossible. La plupart des incidents Terraform sérieux viennent d’un mauvais usage du state, du locking, du drift ou d’une mauvaise isolation.
Backend distant : standard professionnel

En local, Terraform écrit par défaut un fichier terraform.tfstate. C’est acceptable pour apprendre, mais dangereux en équipe et interdit pour une production sérieuse. Un backend distant centralise le state, protège son accès et permet le verrouillage.

Local state vs remote state
ModeUsageLimite
LocalFormation, test personnel, prototype jetable.Risque de perte, conflit, commit accidentel.
S3 + DynamoDBStandard fréquent sur AWS.Nécessite sécurisation bucket/table.
GitLab managed statePratique avec GitLab CI/CD.Dépend de la plateforme GitLab.
Terraform Cloud / EnterpriseCollaboration, policy, remote runs, audit.Solution plus structurée, parfois payante.
Azure Storage / GCSBackends cloud natifs Azure ou GCP.À configurer avec IAM et chiffrement.
Exemple backend S3 + lock DynamoDB
terraform {
                            backend "s3" {
                            bucket         = "company-terraform-state-prod"
                            key            = "prod/network/terraform.tfstate"
                            region         = "eu-west-3"
                            dynamodb_table = "terraform-locks"
                            encrypt        = true
                            }
                            }
Bonne pratique : activer versioning, chiffrement, accès restreint et journalisation sur le bucket qui contient le state.
Ce que doit garantir le backend
GarantiePourquoi
CentralisationToute l’équipe et la CI/CD utilisent la même source de vérité.
LockingEmpêcher deux apply simultanés sur le même state.
VersioningPermettre restauration après corruption ou erreur humaine.
ChiffrementProtéger données internes et secrets potentiels.
Contrôle d’accèsLimiter lecture/écriture aux pipelines et admins autorisés.
AuditSavoir qui a lu ou modifié le state.
Architecture backend
GitLab CI/CD ou poste autorisé
                            │
                            ▼
                            terraform init
                            │
                            ▼
                            Backend distant
                            ├── state chiffré
                            ├── versioning
                            ├── accès IAM restreint
                            └── mécanisme de lock
                            │
                            ▼
                            terraform plan / apply
                            │
                            ▼
                            State mis à jour proprement
Erreur fréquente : protéger l’infrastructure cloud mais laisser le bucket state trop ouvert. Le state donne une vue très détaillée de l’infrastructure.
Locking : empêcher les apply concurrents

Le locking empêche deux exécutions Terraform d’écrire simultanément dans le même state. Sans verrouillage, deux pipelines ou deux ingénieurs peuvent modifier le même state au même moment, avec un risque de corruption, de conflit ou de plan incohérent.

Diagramme de verrouillage
Pipeline A démarre terraform apply
                            │
                            ▼
                            Lock du state obtenu
                            │
                            ├── Pipeline A peut lire / écrire
                            │
                            └── Pipeline B doit attendre
                            │
                            ▼
                            erreur ou attente selon backend
                            │
                            ▼
                            Pipeline A termine
                            │
                            ▼
                            Lock libéré
                            │
                            ▼
                            Pipeline B peut relancer proprement
Sans locking
SituationRisque
Deux apply en parallèleÉcriture concurrente dans le state.
Plan obsolète appliquéLe plan ne reflète plus la réalité.
Pipeline relancé trop viteÉtat partiel ou changement déjà appliqué.
Force unlock abusifDéverrouillage alors qu’un apply est encore actif.
Que faire en cas de state lock ?
ÉtapeAction correcte
1. IdentifierRegarder quel pipeline ou utilisateur détient le lock.
2. AttendreSi l’apply est actif, ne rien forcer.
3. VérifierConfirmer que le job est terminé ou mort.
4. DéverrouillerUtiliser force-unlock seulement si le lock est orphelin.
5. ReplanifierRelancer terraform plan avant tout nouvel apply.
Commande de dernier recours
terraform force-unlock LOCK_ID
Attention : force-unlock ne doit jamais être utilisé par réflexe. Il faut d’abord vérifier qu’aucun apply réel n’est encore en cours.
Règle CI/CD
Un environnement = un state = une file d'exécution contrôlée

                            prod/network apply
                            │
                            └── un seul job actif à la fois
Isolation du state par environnement et domaine

L’isolation du state réduit le blast radius. Il ne faut pas tout mettre dans un seul state global, surtout en production. Un state trop gros rend les plans illisibles, ralentit les pipelines et augmente les risques d’incident.

Mauvaise approche
Un seul state global
                            │
                            ├── dev
                            ├── staging
                            ├── prod
                            ├── network
                            ├── compute
                            ├── database
                            ├── IAM
                            └── monitoring
Problème : un changement mineur peut charger, verrouiller ou impacter une énorme partie de l’infrastructure.
Bonne approche
States séparés
                            │
                            ├── dev/network
                            ├── dev/app
                            ├── dev/data
                            │
                            ├── staging/network
                            ├── staging/app
                            ├── staging/data
                            │
                            ├── prod/network
                            ├── prod/app
                            └── prod/data
Découpage recommandé
StateContenuFréquence de changement
prod/networkVPC, subnets, routes, NAT.Rare
prod/securityIAM, KMS, security groups globaux.Faible à moyenne
prod/appCompute, load balancer, autoscaling.Moyenne à forte
prod/dataDatabases, caches, buckets critiques.Rare et sensible
prod/monitoringDashboards, alarms, log groups.Moyenne
Partager des valeurs entre states
data "terraform_remote_state" "network" {
                            backend = "s3"

                            config = {
                            bucket = "company-terraform-state-prod"
                            key    = "prod/network/terraform.tfstate"
                            region = "eu-west-3"
                            }
                            }

                            locals {
                            vpc_id = data.terraform_remote_state.network.outputs.vpc_id
                            }
Attention : terraform_remote_state crée un couplage entre states. Il faut l’utiliser proprement et exposer seulement les outputs nécessaires.
Sécurité du state Terraform

Le state peut contenir des informations sensibles ou stratégiques : endpoints privés, structure réseau, IDs IAM, parfois tokens ou mots de passe selon les ressources. Il faut donc le protéger comme un secret opérationnel.

Risques principaux
RisqueConséquenceProtection
Commit GitFuite durable dans l’historique..gitignore, secret scanning, hooks.
Bucket trop ouvertLecture complète de l’infra.IAM strict, bucket policy, audit logs.
Pas de chiffrementExposition en cas de fuite stockage.Chiffrement côté backend.
Accès CI trop largePipeline compromis = state compromis.Rôles dédiés, variables protégées, environnements protégés.
Outputs sensiblesSecrets visibles dans logs ou UI.sensitive = true et outputs minimaux.
.gitignore minimal
.terraform/
                            *.tfstate
                            *.tfstate.*
                            crash.log
                            crash.*.log
                            *.tfvars
                            *.tfvars.json
                            override.tf
                            override.tf.json
                            *_override.tf
                            *_override.tf.json
Règle : ne jamais commiter un .tfstate. Si cela arrive, il faut considérer qu’il y a eu fuite et nettoyer aussi l’historique Git.
Contrôles de sécurité recommandés
ContrôleNiveau pro attendu
ChiffrementState chiffré au repos.
VersioningHistorique récupérable en cas d’erreur.
IAMLecture/écriture limitée aux rôles nécessaires.
Audit logsTraçabilité des accès au backend.
Protected variablesCredentials injectés uniquement sur branches/environnements autorisés.
RotationRotation des credentials utilisés par CI/CD.
Secrets et state
Variable sensitive
                            │
                            ├── masque l'affichage CLI
                            └── ne garantit pas l'absence dans le state
                            │
                            ▼
                            Secret manager préférable
                            ├── Vault
                            ├── AWS Secrets Manager
                            ├── SSM Parameter Store
                            └── GitLab protected variables
Bonne approche : éviter de faire transiter les secrets dans Terraform quand ce n’est pas nécessaire. Utiliser plutôt les mécanismes natifs de secrets management.
Drift : quand la réalité ne correspond plus au code

Le drift apparaît quand l’infrastructure réelle ne correspond plus au code Terraform ou au state. Il est souvent causé par une modification manuelle dans la console cloud, un hotfix urgent, une ressource supprimée hors Terraform ou un import incomplet.

Diagramme du drift
Code Terraform
                            instance_type = "t3.small"

                            State Terraform
                            instance_type = "t3.small"

                            Cloud réel
                            instance_type = "t3.medium"

                            Résultat :
                            terraform plan détecte un écart
                            et propose de revenir à t3.small
Causes fréquentes
CauseExempleRisque
ClickOpsModification console AWS hors Terraform.Plan inattendu.
Hotfix urgenceOuverture temporaire d’un security group.Dette de sécurité.
Suppression externeRessource supprimée par erreur hors Terraform.Recréation ou erreur apply.
Import incompletRessource existante rattachée partiellement.Diff permanent.
Provider changeNouvelle version modifie attributs calculés.Plan bruyant ou instable.
Réaction professionnelle au drift
Drift détecté
                            │
                            ▼
                            Ne pas appliquer automatiquement
                            │
                            ▼
                            Comprendre l'écart
                            │
                            ├── changement manuel légitime ?
                            ├── incident ou hotfix ?
                            ├── bug provider ?
                            └── ressource supprimée ?
                            │
                            ▼
                            Décision
                            ├── intégrer le changement dans le code
                            ├── restaurer l'état attendu
                            ├── importer correctement
                            └── documenter la décision
Commandes utiles
terraform plan
                            terraform plan -refresh-only
                            terraform apply -refresh-only
                            terraform state list
                            terraform state show RESOURCE_NAME
Attention : un drift ne doit pas être “corrigé” à l’aveugle. Il peut révéler un hotfix de production, un incident ou une modification de sécurité.
Politique anti-drift
Interdire ClickOpsSauf urgence documentée.
Plan régulierDétection proactive des écarts.
Audit cloudIdentifier les modifications hors pipeline.
Runbook hotfixTout hotfix manuel doit être reporté dans Terraform.
Import, state mv, state rm : opérations sensibles

Les commandes de manipulation du state sont puissantes et dangereuses. Elles servent à rattacher des ressources existantes, renommer des ressources dans le state, ou retirer une ressource du state sans la détruire réellement.

Commandes principales
CommandeUsageDanger
terraform importRattacher une ressource existante au state.Import incomplet si le code ne correspond pas.
terraform state mvDéplacer ou renommer une ressource dans le state.Erreur de mapping.
terraform state rmRetirer une ressource du state sans la supprimer.Terraform ne la gère plus.
terraform state showInspecter une ressource connue.Peut afficher données sensibles.
terraform state pullExporter le state courant.Fichier sensible localement.
Exemple import
# 1. Écrire d'abord le bloc resource correspondant
                            resource "aws_security_group" "web" {
                            name   = "prod-web-sg"
                            vpc_id = var.vpc_id
                            }

                            # 2. Importer la ressource existante
                            terraform import aws_security_group.web sg-0123456789abcdef0

                            # 3. Lancer un plan pour aligner code et réalité
                            terraform plan
Renommer une ressource sans recréation
# Ancien nom dans le state
                            aws_instance.web

                            # Nouveau nom dans le code
                            aws_instance.application

                            # Déplacement dans le state
                            terraform state mv aws_instance.web aws_instance.application
Processus sécurisé
Avant manipulation state
                            │
                            ├── sauvegarder state
                            ├── comprendre mapping actuel
                            ├── préparer commande exacte
                            ├── faire revue par un pair
                            └── exécuter hors période critique
                            │
                            ▼
                            Après manipulation
                            ├── terraform plan
                            ├── vérifier zéro destruction inattendue
                            └── documenter l'opération
Règle : ne jamais utiliser state rm pour “faire disparaître une erreur” sans comprendre pourquoi Terraform voulait gérer cette ressource.
Incidents liés au state : scénarios réels
Scénario 1 : state local commité dans Git
ÉtapeRéaction
DétectionUn fichier .tfstate apparaît dans le repo.
RisqueFuite d’informations internes ou secrets.
Action immédiateSupprimer du repo, bloquer push, analyser contenu.
Action sécuritéRotation des secrets potentiellement exposés.
Prévention.gitignore, secret scanning, formation équipe.
Scénario 2 : lock bloqué
Pipeline échoue brutalement
                            │
                            ▼
                            Lock reste présent
                            │
                            ▼
                            Nouveau plan/apply impossible
                            │
                            ▼
                            Vérifier qu'aucun apply ne tourne
                            │
                            ▼
                            force-unlock uniquement si lock orphelin
                            │
                            ▼
                            relancer terraform plan
Scénario 3 : mauvais state utilisé
CauseConséquencePrévention
Backend mal configuréPlan prod exécuté sur state staging ou inversement.Clés backend explicites, pipeline par environnement.
Workspace mal choisiChangements appliqués au mauvais contexte.Éviter workspaces pour séparation critique si équipe peu mature.
Variables mélangéesRessources prod avec paramètres dev.tfvars contrôlés et environnements protégés.
Scénario 4 : state corrompu ou perdu
  1. Stopper les applies immédiatement.
  2. Récupérer une version précédente du backend.
  3. Comparer avec l’infrastructure réelle.
  4. Restaurer le state si possible.
  5. Importer manuellement les ressources si nécessaire.
  6. Documenter la cause et renforcer les protections.
Objectif incident : éviter le réflexe “on relance apply”. Sur incident state, la priorité est de comprendre et préserver la cohérence.
Outils liés au state, drift et sécurité Terraform
Outils Terraform natifs
Outil / commandeUtilité
terraform state listVoir toutes les ressources connues du state.
terraform state showInspecter une ressource précise.
terraform plan -refresh-onlyObserver les écarts entre state et cloud réel.
terraform importRattacher une ressource existante.
terraform force-unlockDéverrouiller un lock orphelin.
terraform outputAfficher les outputs utiles d’un state.
Commandes utiles
terraform state list
                            terraform state show aws_instance.web
                            terraform plan -refresh-only
                            terraform apply -refresh-only
                            terraform output
                            terraform state pull > state-backup.json
Outils complémentaires
OutilUsage
GitLab CI/CDContrôler plans/applies et protéger environnements.
Terraform CloudRemote state, runs, policies, audit, collaboration.
AtlantisPlans Terraform déclenchés depuis merge requests.
SpaceliftOrchestration IaC, drift detection, policies.
Checkov / tfsec / TrivyScan sécurité du code IaC.
CloudTrail / audit logsIdentifier les changements hors Terraform.
Cost toolsEstimer l’impact financier d’un plan.
Niveau pro : combiner Terraform avec CI/CD, audit cloud, scan sécurité et détection de drift donne une exploitation beaucoup plus fiable.
Anti-patterns State Terraform
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
State commité dans GitFuite de données sensibles et historique difficile à nettoyer.Backend distant + .gitignore + secret scanning.
Un state pour toutBlast radius énorme, plans lents, verrou global.Découper par environnement et domaine.
Pas de lockingRisque d’applies concurrents et state incohérent.Backend avec verrouillage actif.
force-unlock réflexePeut casser un apply encore actif.Vérifier pipeline/job avant toute action.
ClickOps permanentDrift permanent et Terraform devient imprévisible.Tout changement durable revient dans le code.
Outputs sensiblesSecrets visibles dans logs ou autres states.Outputs minimaux et marqués sensitive si nécessaire.
Manipulation state sans backupPerte de mapping ou destruction involontaire future.Sauvegarde, revue, plan post-opération.
Workspace utilisé pour toutConfusion possible entre dev/staging/prod.Backends et dossiers explicites pour environnements critiques.
Mauvais modèle
terraform.tfstate local
                            │
                            ├── partagé par email ou Slack
                            ├── parfois commité
                            ├── pas de lock
                            ├── pas de versioning
                            └── dev/staging/prod mélangés
Résultat : production fragile, difficile à auditer et risquée à modifier.
Modèle professionnel
remote backend
                            │
                            ├── state chiffré
                            ├── versioning
                            ├── locking
                            ├── IAM strict
                            ├── audit logs
                            └── séparation env/domaine
Résultat : changements plus sûrs, meilleure collaboration, récupération possible en cas d’erreur.
Checklist professionnelle State Terraform
Checklist backend
PointValidation attendue
Backend distantLe state n’est pas local en production.
LockingDeux apply concurrents sont empêchés.
VersioningUne version précédente du state peut être restaurée.
ChiffrementLe state est chiffré au repos.
Accès limitéSeuls les rôles autorisés peuvent lire/écrire.
AuditLes accès au backend sont traçables.
BackupProcédure de récupération connue et testée.
Checklist isolation
Un state par environnementDev, staging et prod séparés.
Un state par domaine sensibleNetwork, app, data séparés si nécessaire.
Outputs limitésRemote state expose uniquement le nécessaire.
Pas de state énormePlan lisible et verrouillage limité.
Checklist avant apply production
QuestionPourquoi
Le bon backend est-il utilisé ?Éviter d’appliquer sur le mauvais environnement.
Le state est-il verrouillé ?Éviter les exécutions concurrentes.
Le plan montre-t-il des destructions ?Identifier les risques majeurs.
Y a-t-il du drift ?Comprendre si le réel a changé hors Terraform.
Les outputs sont-ils non sensibles ?Éviter la fuite d’informations.
Existe-t-il une procédure de retour arrière ?Réagir vite en cas d’incident.
L’accès CI/CD est-il limité ?Réduire le blast radius d’un runner compromis.
Définition d’un state bien géré : distant, verrouillé, chiffré, versionné, isolé, audité et manipulé uniquement par des workflows contrôlés.
Mini-cheat-sheet
terraform init
                            terraform state list
                            terraform state show RESOURCE_NAME
                            terraform plan -refresh-only
                            terraform apply -refresh-only
                            terraform import RESOURCE_NAME PROVIDER_ID
                            terraform state mv OLD_NAME NEW_NAME
                            terraform state rm RESOURCE_NAME
                            terraform force-unlock LOCK_ID
2.1 GitLab CI/CD Infra : pipeline Terraform professionnel
GitLab CI/CD côté infrastructure

GitLab CI/CD permet d’industrialiser les changements d’infrastructure : formatage, validation, scan sécurité, génération du plan Terraform, revue humaine, approval, apply contrôlé et vérifications post-déploiement.

Le but n’est pas seulement d’automatiser. Le but est de rendre chaque changement reproductible, traçable, reviewable et limité en risque.

Objectif professionnel : aucun changement infrastructure production ne devrait être appliqué sans pipeline, plan relu, environnement protégé et trace d’audit.
Ce que GitLab apporte à Terraform
Besoin infraRéponse GitLab CI/CD
Standardiser les commandesLes mêmes jobs exécutent toujours fmt, validate, plan.
Tracer les changementsChaque pipeline est lié à un commit, une branche, une MR et un utilisateur.
Contrôler la productionBranches protégées, environnements protégés, jobs manuels, approvals.
Sécuriser les secretsVariables masked/protected, scopes par environnement.
Conserver les preuvesArtefacts de plan, logs de pipeline, historique d’exécution.
Réduire les erreurs humainesMoins de commandes manuelles locales, moins de divergence entre postes.
Vision globale
Développeur / DevOps
                            │
                            ▼
                            Branche Git
                            │
                            ▼
                            Merge Request
                            │
                            ├── terraform fmt
                            ├── terraform validate
                            ├── scans sécurité
                            ├── terraform plan
                            └── artefact du plan
                            │
                            ▼
                            Revue humaine
                            │
                            ▼
                            Approval protégé
                            │
                            ▼
                            terraform apply
                            │
                            ▼
                            Post-deploy checks
                            ├── health checks
                            ├── logs
                            ├── métriques
                            └── rollback / mitigation si besoin
GitLab ne remplace pas la revue humaine

Le pipeline produit des signaux fiables : erreurs de syntaxe, diff Terraform, scans sécurité, artefacts. Mais la décision de production reste une décision humaine ou une décision gouvernée par des règles d’équipe.

Règle : automatiser l’exécution, mais protéger la décision. Surtout pour les environnements staging, preprod et prod.
Pipeline infra recommandé

Un pipeline infrastructure sérieux doit séparer les étapes de qualité, sécurité, plan, revue, apply et vérification. Le plan doit être visible avant toute modification réelle.

Chaîne complète
Commit / Merge Request
                            │
                            ▼
                            lint
                            ├── terraform fmt
                            └── tflint
                            │
                            ▼
                            validate
                            ├── terraform init
                            └── terraform validate
                            │
                            ▼
                            security
                            ├── checkov
                            ├── tfsec / trivy config
                            └── secret detection
                            │
                            ▼
                            plan
                            ├── terraform plan
                            ├── plan lisible
                            └── artefact conservé
                            │
                            ▼
                            review
                            ├── revue du diff
                            ├── revue des destructions
                            └── approval
                            │
                            ▼
                            apply
                            ├── manuel en production
                            ├── environnement protégé
                            └── state verrouillé
                            │
                            ▼
                            post-checks
                            ├── smoke tests
                            ├── logs
                            ├── métriques
                            └── alertes
Bonne pratique : sur merge request, on génère un plan. Sur branche protégée, on autorise éventuellement l’apply.
Stages typiques
StageButBloquant ?
fmtVérifier le format Terraform.Oui
validateValider syntaxe, providers, modules.Oui
securityDétecter ports ouverts, IAM trop larges, secrets.Oui ou warning selon maturité.
planAfficher exactement ce que Terraform veut changer.Oui
reviewRelire le plan et décider.Oui pour prod
applyModifier réellement l’infrastructure.Manuel/protégé pour prod
post_checkVérifier santé réelle après changement.Oui si critique
Politique par environnement
EnvironnementPlanApply
devAutomatiqueAutomatique ou manuel simple
stagingAutomatiqueManuel avec validation équipe
prodAutomatique, archivéManuel, protégé, approbation requise
Attention : un apply automatique en production est rarement acceptable pour une infrastructure critique.
Exemple complet de .gitlab-ci.yml pour Terraform

Exemple pédagogique : pipeline avec formatage, validation, scan sécurité, plan archivé et apply manuel en production.

stages:
                    - lint
                    - validate
                    - security
                    - plan
                    - apply
                    - post_check

                    variables:
                    TF_IN_AUTOMATION: "true"
                    TF_INPUT: "false"
                    TF_ROOT: "infra/live/prod/app"
                    TF_PLAN_FILE: "tfplan"

                    default:
                    image: hashicorp/terraform:1.6.6
                    before_script:
                    - cd "$TF_ROOT"
                    - terraform --version
                    - terraform init

                    terraform_fmt:
                    stage: lint
                    script:
                    - terraform fmt -check -recursive
                    rules:
                    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
                    - if: '$CI_COMMIT_BRANCH == "main"'

                    terraform_validate:
                    stage: validate
                    script:
                    - terraform validate
                    rules:
                    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
                    - if: '$CI_COMMIT_BRANCH == "main"'

                    terraform_security_scan:
                    stage: security
                    image: bridgecrew/checkov:latest
                    before_script: []
                    script:
                    - checkov -d infra
                    allow_failure: false
                    rules:
                    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
                    - if: '$CI_COMMIT_BRANCH == "main"'

                    terraform_plan:
                    stage: plan
                    script:
                    - terraform plan -out="$TF_PLAN_FILE" -var-file="prod.tfvars"
                    - terraform show -no-color "$TF_PLAN_FILE" > plan.txt
                    artifacts:
                    name: "terraform-plan-$CI_COMMIT_SHORT_SHA"
                    paths:
                    - "$TF_ROOT/$TF_PLAN_FILE"
                    - "$TF_ROOT/plan.txt"
                    expire_in: 3 days
                    rules:
                    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
                    - if: '$CI_COMMIT_BRANCH == "main"'

                    terraform_apply_prod:
                    stage: apply
                    script:
                    - terraform apply -auto-approve "$TF_PLAN_FILE"
                    dependencies:
                    - terraform_plan
                    environment:
                    name: production
                    when: manual
                    allow_failure: false
                    rules:
                    - if: '$CI_COMMIT_BRANCH == "main"'

                    post_deploy_checks:
                    stage: post_check
                    image: alpine:latest
                    before_script: []
                    script:
                    - echo "Run health checks, smoke tests, metrics checks here"
                    needs:
                    - terraform_apply_prod
                    rules:
                    - if: '$CI_COMMIT_BRANCH == "main"'
Points importants dans ce YAML
ÉlémentRôle
TF_IN_AUTOMATIONIndique à Terraform qu’il tourne dans une CI.
TF_INPUT=falseÉvite les prompts interactifs bloquants.
artifactsConserve le plan binaire et le plan lisible.
when: manualForce un clic humain pour appliquer en production.
environmentLie le job à un environnement GitLab protégé.
Limites de cet exemple
  • Il faut adapter le backend Terraform à votre organisation.
  • Il faut configurer les variables cloud dans GitLab de manière protégée.
  • Il faut éviter de dupliquer trop de YAML si plusieurs environnements existent.
  • Il faut prévoir un plan par environnement ou par domaine infra.
Évolution pro : factoriser avec include, templates GitLab, variables par environnement et jobs réutilisables.
GitLab Runners : exécuter les pipelines proprement

Un runner GitLab exécute les jobs CI/CD. Côté infrastructure, il est très sensible, car il peut avoir accès à des credentials cloud, au state Terraform et parfois à des environnements critiques.

Types de runners
TypeUsageRisque
Shared runnerJobs génériques, projets peu sensibles.Moins de contrôle sur l’environnement.
Group runnerStandard d’équipe ou de département.Attention aux droits transverses.
Project runnerProjet spécifique, meilleur cloisonnement.Maintenance dédiée.
Protected runnerBranches/tags protégés seulement.Recommandé pour production.
Self-hosted runnerContrôle total réseau, IAM, packages.Responsabilité sécurité plus forte.
Tags runner
terraform_apply_prod:
                            stage: apply
                            tags:
                            - terraform
                            - prod
                            - protected
                            script:
                            - terraform apply -auto-approve tfplan
Bonne pratique : utiliser des runners dédiés et protégés pour les jobs capables de modifier la production.
Architecture runner sécurisée
GitLab
                            │
                            ▼
                            Protected Runner
                            │
                            ├── exécute seulement branches protégées
                            ├── utilise credentials limités
                            ├── accès réseau contrôlé
                            ├── logs surveillés
                            └── isolation Docker / VM
                            │
                            ▼
                            Terraform
                            │
                            ├── remote state
                            ├── cloud provider
                            └── environnement prod
Risques runner
RisquePrévention
Runner non protégéLimiter les jobs prod aux branches protégées.
Credentials trop largesIAM minimal par environnement.
Logs exposant secretsVariables masked, pas de echo de secrets.
Runner partagé trop largeRunner dédié infra pour jobs sensibles.
Image CI non maîtriséeImages versionnées et scannées.
Point critique : un runner qui peut faire terraform apply en production est une cible sensible. Il doit être traité comme un composant de sécurité.
Variables GitLab, secrets et environnements

Les variables CI/CD servent à injecter credentials cloud, paramètres Terraform, chemins, tokens, noms d’environnement et options d’exécution. Leur mauvaise gestion est l’une des causes majeures d’incidents ou de fuites.

Types de variables
TypeUsageProtection recommandée
Cloud credentialsAccès AWS, Azure, GCP.Masked + protected + scope environnement.
Terraform varsTF_VAR_* pour injecter variables Terraform.Protected si prod.
Backend configBucket, key, région, workspace.Variables non sensibles mais contrôlées.
Tokens outilsCheckov, Vault, GitLab API, registry.Masked + rotation régulière.
Feature flagsActiver scan, debug, apply auto dev.Selon contexte.
Exemple TF_VAR
# Variable GitLab CI/CD
                            TF_VAR_project=ideo-platform
                            TF_VAR_environment=prod
                            TF_VAR_aws_region=eu-west-3

                            # Terraform la récupère automatiquement :
                            variable "project" {
                            type = string
                            }
Masked, protected, scoped
Option GitLabRôle
MaskedMasque la valeur dans les logs.
ProtectedDisponible seulement pour branches/tags protégés.
Environment scopeLimite la variable à un environnement précis.
File variableStocke certificat, kubeconfig ou clé sous forme de fichier temporaire.
Flux sécurisé
GitLab protected variables
                            │
                            ├── accessibles uniquement sur main/protected
                            ├── masquées dans les logs
                            ├── scopées à production
                            └── injectées au job apply
                            │
                            ▼
                            Terraform
                            ├── utilise credentials temporaires si possible
                            └── évite secrets en clair dans Git
Attention : une variable masquée n’est pas une stratégie de secrets complète. Il faut aussi gérer les droits, la rotation, les scopes et l’audit.
Review du plan Terraform

La revue du plan est l’étape la plus importante avant un apply. Le pipeline doit produire un plan lisible, stable et archivé pour que l’équipe puisse décider en connaissance de cause.

Ce qu’il faut relire
PointQuestion à poserDanger
DestroyY a-t-il des suppressions ?Perte de service ou données.
ReplaceUne ressource est-elle recréée ?Downtime, perte d’IP, remplacement DB.
Security groupUn port est-il ouvert trop largement ?Exposition sécurité.
IAMUne policy donne-t-elle trop de droits ?Escalade de privilèges.
DatabaseBackup, storage, deletion protection changent-ils ?Risque data.
ScopeLe plan concerne-t-il le bon environnement ?Erreur dev/prod.
SecretsUne valeur sensible apparaît-elle ?Fuite logs/artifacts.
Règle : toute ligne destroy ou replace en production exige une justification explicite.
Lecture du plan
SymboleSignificationRéflexe
+Création.Vérifier coût, tags, sécurité.
~Modification in-place.Vérifier impact réel.
-/+Remplacement.Analyse obligatoire.
-Suppression.Stop si non attendu.
Diagramme review
Plan généré
                            │
                            ▼
                            Revue automatique
                            ├── fmt
                            ├── validate
                            ├── security
                            └── policy
                            │
                            ▼
                            Revue humaine
                            ├── scope
                            ├── destroy / replace
                            ├── réseau / IAM
                            ├── database
                            └── rollback
                            │
                            ▼
                            Approval ou rejet
Commentaire MR recommandé
Résumé infra :
                            - Environnement : production
                            - Domaine : app
                            - Ressources créées : 2
                            - Ressources modifiées : 1
                            - Ressources détruites : 0
                            - Risque : faible
                            - Rollback : revenir au commit précédent + plan/apply
                            - Vérification : health check /metrics + logs applicatifs
Apply protégé en production

L’étape apply modifie réellement l’infrastructure. En production, elle doit être limitée, tracée, contrôlée et idéalement exécutée depuis un environnement GitLab protégé.

Garde-fous GitLab
Garde-fouBut
Protected branchEmpêcher un apply depuis une branche non validée.
Protected environmentLimiter qui peut déployer en production.
Manual jobForcer une décision humaine.
ApprovalsExiger validation d’un ou plusieurs responsables.
Protected variablesRendre les credentials prod disponibles uniquement dans le bon contexte.
Runner dédiéRéduire la surface d’attaque.
Exemple job apply prod
terraform_apply_prod:
                            stage: apply
                            environment:
                            name: production
                            script:
                            - terraform apply -auto-approve "$TF_PLAN_FILE"
                            dependencies:
                            - terraform_plan
                            when: manual
                            allow_failure: false
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
                            tags:
                            - terraform
                            - prod
                            - protected
Apply contrôlé : flux opérationnel
Merge sur main
                            │
                            ▼
                            Pipeline prod
                            │
                            ├── validate
                            ├── security
                            └── plan
                            │
                            ▼
                            Plan relu
                            │
                            ▼
                            Approval environnement production
                            │
                            ▼
                            Job apply manuel
                            │
                            ▼
                            State lock
                            │
                            ▼
                            terraform apply
                            │
                            ▼
                            post-checks
Avant de cliquer Apply
Le plan a-t-il été relu ?Oui obligatoire.
Le plan contient-il destroy/replace ?Justification obligatoire.
Le bon environnement est-il ciblé ?Prod vs staging vérifié.
Le state est-il verrouillé correctement ?Backend distant actif.
Le rollback ou mitigation est-il connu ?Oui avant apply.
Attention : -auto-approve est acceptable en CI uniquement si le job est manuel, protégé et basé sur un plan déjà relu.
Rollback et mitigation côté infrastructure

Le rollback Terraform n’est pas toujours aussi simple qu’un rollback applicatif. Certains changements peuvent être inversés en revenant au commit précédent, mais d’autres nécessitent une mitigation spécifique, surtout pour les bases de données, réseaux et IAM.

Rollback : cas possibles
SituationRéaction possibleRisque
Security group trop restrictifRevenir au commit précédent ou hotfix Terraform.Service inaccessible.
IAM policy casséeRestaurer policy précédente.Jobs/applications bloqués.
Load balancer mal configuréRevenir listener/target group.Downtime web.
Database modifiéeMitigation, restore ou correction manuelle contrôlée.Risque data élevé.
Ressource suppriméeRecréation ou restauration backup.Perte possible si state/data mal protégés.
Rollback par commit précédent
Incident après apply
                            │
                            ▼
                            Identifier commit fautif
                            │
                            ▼
                            Créer revert commit
                            │
                            ▼
                            Pipeline terraform plan
                            │
                            ▼
                            Relire plan de rollback
                            │
                            ▼
                            Apply contrôlé
                            │
                            ▼
                            Vérifier service
Mitigation vs rollback
ApprocheQuand l’utiliser
RollbackQuand revenir à l’état précédent est sûr et rapide.
MitigationQuand il faut restaurer le service sans forcément revenir totalement en arrière.
Hotfix TerraformQuand une correction rapide doit rester versionnée.
Action manuelle d’urgenceDernier recours, puis report obligatoire dans Terraform.
Runbook rollback minimal
1. Déclarer l'incident.
                            2. Identifier le dernier apply Terraform.
                            3. Lire le plan appliqué et le commit associé.
                            4. Vérifier l'impact : réseau, IAM, DB, compute.
                            5. Choisir : rollback commit, hotfix Terraform ou mitigation.
                            6. Générer un nouveau plan.
                            7. Faire relire le plan.
                            8. Appliquer.
                            9. Vérifier santé service.
                            10. Documenter postmortem.
Règle production : ne jamais lancer un rollback Terraform à l’aveugle. Le plan de rollback peut lui aussi contenir des destructions.
Sécurité GitLab CI/CD pour l’infra

Un pipeline infrastructure a souvent les droits de modifier la production. Il doit donc être conçu comme une surface critique : contrôle des branches, variables, runners, images Docker, logs, permissions et approvals.

Contrôles indispensables
ContrôlePourquoi
Branches protégéesEmpêcher un apply prod depuis une branche arbitraire.
Variables protégéesLimiter les credentials prod au contexte autorisé.
Environnements protégésLimiter qui peut déployer en production.
Runner protégéÉviter exécution prod sur runner non contrôlé.
Images CI pinéesÉviter image flottante compromise ou changeante.
Scan IaCDétecter mauvaises pratiques avant merge.
Secret detectionEmpêcher commit de tokens ou clés.
Exemple de sécurité job
terraform_apply_prod:
                            stage: apply
                            when: manual
                            protected: true
                            environment:
                            name: production
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
                            tags:
                            - protected
                            - prod
Threat model simple
Risque
                            │
                            ├── MR malveillante
                            ├── variable exposée
                            ├── runner compromis
                            ├── image CI compromise
                            ├── plan non relu
                            └── accès cloud trop large
                            │
                            ▼
                            Contrôles
                            ├── protected branches
                            ├── approvals
                            ├── masked variables
                            ├── least privilege IAM
                            ├── runner dédié
                            ├── scan IaC
                            └── audit logs
Outils sécurité liés
OutilUsage
CheckovScan Terraform et politiques cloud.
tfsecDétection de mauvaises pratiques Terraform.
Trivy configScan IaC, containers, dépendances.
GitLab Secret DetectionDétecter secrets committés.
Vault / Secrets ManagerGestion des secrets hors GitLab si nécessaire.
Niveau pro : un pipeline Terraform doit appliquer le principe du moindre privilège comme n’importe quel composant applicatif critique.
Debug GitLab CI/CD Infra
Problèmes fréquents
SymptômeCause probableRéflexe
Job pendingAucun runner disponible ou tags incorrects.Vérifier runners, tags, protection.
Variable videVariable protected non disponible sur branche non protégée.Contrôler protected branch et scope.
terraform init échoueBackend inaccessible ou credentials invalides.Vérifier IAM, backend, réseau.
State lockAutre pipeline actif ou lock orphelin.Identifier job actif avant force-unlock.
Plan différent local/CIVersions Terraform/providers ou variables différentes.Pinner versions, comparer variables.
Apply refuse permissionRôle cloud insuffisant.Corriger IAM avec moindre privilège.
Artifact manquantMauvais chemin ou dépendance job.Vérifier paths, dependencies, needs.
Commandes utiles
# Runner
                            gitlab-runner verify
                            gitlab-runner list

                            # Terraform
                            terraform --version
                            terraform providers
                            terraform init
                            terraform validate
                            terraform plan -refresh-only
                            terraform state list

                            # Lock, uniquement après analyse
                            terraform force-unlock LOCK_ID
Méthode de debug
Pipeline échoue
                            │
                            ▼
                            Identifier le job exact
                            │
                            ▼
                            Lire logs du haut vers le bas
                            │
                            ├── image utilisée
                            ├── variables disponibles
                            ├── dossier courant
                            ├── terraform init
                            ├── backend
                            └── provider error
                            │
                            ▼
                            Corriger la cause minimale
                            │
                            ▼
                            Relancer uniquement le job nécessaire
Attention : ne jamais ajouter echo $SECRET pour debugger. Utiliser des tests indirects et des variables masquées.
Checklist GitLab CI/CD Infrastructure
Checklist pipeline
PointValidation attendue
Stages séparésfmt, validate, security, plan, apply, post-check.
Terraform versionnéVersion Terraform et providers fixées.
Plan archivéPlan binaire et plan lisible disponibles en artifacts.
Apply manuel prodJamais automatique sans contrôle explicite.
Environnement protégéProduction limitée aux personnes autorisées.
Runner contrôléRunner protégé, taggé, accès limité.
Variables sécuriséesMasked, protected, scoped.
Scans sécuritéCheckov/tfsec/Trivy/secret detection selon contexte.
Checklist avant apply production
QuestionPourquoi
Le plan est-il celui du commit validé ?Éviter d’appliquer un autre contenu.
Y a-t-il destroy ou replace ?Risque majeur sur service ou données.
Le bon environnement est-il ciblé ?Éviter erreur staging/prod.
Le state est-il distant et verrouillé ?Éviter conflit ou corruption.
Les credentials sont-ils limités ?Réduire le blast radius.
Le rollback est-il clair ?Réagir vite en cas d’incident.
Les checks post-déploiement existent-ils ?Confirmer que la production est saine.
Définition d’un pipeline infra mature : il rend les changements visibles, relisibles, sécurisés, approuvés, traçables et vérifiables après exécution.
Mini-cheat-sheet
terraform fmt -check -recursive
                            terraform init
                            terraform validate
                            terraform plan -out=tfplan
                            terraform show -no-color tfplan > plan.txt
                            terraform apply tfplan
                            terraform plan -refresh-only
                            terraform state list
2.2 Environnements : dev, staging, prod et séparation professionnelle
Pourquoi séparer les environnements ?

Dev, staging et production n’ont pas les mêmes objectifs, les mêmes données, les mêmes contraintes de sécurité, ni le même niveau de risque. Les mélanger dans le code, les variables, les credentials ou le state Terraform est une source classique d’incident.

Une bonne séparation permet de tester vite en dev, de valider sérieusement en staging et de protéger fortement la production.

Règle absolue : une feature branch non protégée ne doit jamais avoir accès aux credentials, variables ou states de production.
Différences fondamentales
EnvironnementObjectifNiveau de contrôle
DevExpérimenter, tester rapidement, casser sans impact client.Faible à moyen, apply parfois semi-automatique.
Review appCréer un environnement temporaire pour une merge request.Automatique, durée limitée, ressources jetables.
StagingValider avant production dans un contexte réaliste.Plan, revue, apply contrôlé.
PreprodRépétition quasi identique à la production.Contrôle fort, proche prod.
ProdServir les vrais utilisateurs et données réelles.Plan, approval, fenêtre, rollback, monitoring.
Diagramme de séparation
Branches Git
                            │
                            ├── feature/*
                            │     └── dev / review app
                            │
                            ├── release/*
                            │     └── staging / preprod
                            │
                            └── main
                            └── production

                            Chaque environnement possède :
                            ├── variables dédiées
                            ├── credentials dédiés
                            ├── state Terraform dédié
                            ├── pipeline adapté
                            ├── droits d'accès spécifiques
                            └── politique d'approval différente
Ce qu’il faut isoler
ÉlémentPourquoi l’isoler
Credentials cloudÉviter qu’un job dev puisse modifier la production.
State TerraformÉviter qu’un plan dev lise ou modifie le state prod.
VariablesÉviter mélange des tailles d’instances, régions, DNS, mots de passe.
DonnéesÉviter fuite ou modification de données réelles.
RunnersLimiter les droits prod aux runners protégés.
ApprovalsAppliquer un contrôle fort uniquement là où nécessaire.
Objectif : permettre la vitesse en dev sans sacrifier la sécurité et la stabilité en production.
Modèle cible professionnel

Un modèle mature définit clairement le rôle de chaque environnement, son niveau de ressemblance avec la production, ses droits, sa stratégie de données et sa politique de déploiement.

Tableau de maturité
EnvInfrastructureDonnéesDéploiement
DevRéduite, économique, flexible.Fake data ou anonymisée.Rapide, parfois automatique.
ReviewTemporaire, détruite après MR.Jeu minimal ou fixtures.Automatique par MR.
StagingProche prod mais plus petit.Anonymisée ou snapshot contrôlé.Manuel ou semi-automatique.
PreprodTrès proche prod.Anonymisée, volume représentatif.Répétition avant prod.
ProdHaute disponibilité, monitoring complet.Données réelles.Manuel, protégé, audité.
Nommage recommandé
project     = "ideo-platform"
                            environment = "prod"
                            region      = "eu-west-3"

                            name_prefix = "${project}-${environment}"

                            Exemples :
                            ideo-platform-dev-api
                            ideo-platform-staging-api
                            ideo-platform-prod-api
Architecture cible
Organisation Cloud / GitLab
                            │
                            ├── Dev
                            │     ├── compte/projet ou namespace dédié
                            │     ├── credentials dev
                            │     ├── state dev
                            │     └── budget limité
                            │
                            ├── Staging
                            │     ├── credentials staging
                            │     ├── state staging
                            │     ├── données anonymisées
                            │     └── pipeline contrôlé
                            │
                            └── Production
                            ├── credentials prod
                            ├── state prod
                            ├── variables protégées
                            ├── runner protégé
                            ├── approvals
                            ├── monitoring complet
                            └── runbooks incidents
Stratégie cloud
ApprocheAvantageLimite
Un compte cloud uniqueSimple pour débuter.Isolation faible si IAM mal géré.
Un compte par environnementIsolation forte, très professionnel.Plus d’administration.
Un projet cloud par envBon compromis sur GCP/GitLab.Governance nécessaire.
Multi-account prod stricteSécurité et blast radius très contrôlés.Complexité plus élevée.
Niveau pro : plus l’environnement est critique, plus l’isolation doit être forte : compte/projet dédié, IAM dédié, state dédié, approval dédié.
Mapping GitLab : branches, environnements et pipelines

GitLab permet d’associer des branches, jobs, variables, runners et approvals à des environnements. C’est essentiel pour empêcher une branche non contrôlée d’accéder aux credentials de production.

Mapping recommandé
GitEnvironnementPipelineDroits
feature/*dev ou review appfmt, validate, plan devPas de secrets prod
developdev partagéplan/apply dev possibleCredentials dev
release/*stagingplan + apply manuel stagingCredentials staging
mainproductionplan prod + apply manuelCredentials prod protégés
tag v*release productiondéploiement versionnéApproval fort
Exemple rules GitLab
terraform_plan_prod:
                            stage: plan
                            environment:
                            name: production
                            script:
                            - terraform plan -var-file="prod.tfvars"
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'

                            terraform_apply_prod:
                            stage: apply
                            environment:
                            name: production
                            when: manual
                            script:
                            - terraform apply tfplan
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
Flux GitLab recommandé
feature/*
                            │
                            ├── fmt
                            ├── validate
                            └── plan dev
                            │
                            ▼
                            Merge Request
                            │
                            ├── review code
                            ├── review plan
                            └── scan sécurité
                            │
                            ▼
                            release/*
                            │
                            └── apply staging manuel
                            │
                            ▼
                            main
                            │
                            ├── plan production
                            ├── approval
                            └── apply production manuel
Environnements protégés GitLab
ProtectionRôle
Protected branchesEmpêcher push/merge non autorisé sur main.
Protected environmentsLimiter qui peut exécuter le job prod.
Required approvalsExiger validation avant merge ou deploy.
Scoped variablesLimiter secrets à production/staging/dev.
Runner tagsAssocier les jobs sensibles aux runners protégés.
Erreur critique : donner des variables production à des pipelines de merge request provenant de branches non protégées.
Variables protégées et secrets par environnement

Les variables ne doivent pas être globales si elles donnent accès à des environnements différents. Un secret production doit être disponible uniquement dans un job production, sur branche protégée, avec runner protégé.

Organisation recommandée
VariableScopeProtection
AWS_ACCESS_KEY_ID_DEVdevNon prod, droits limités.
AWS_ACCESS_KEY_ID_STAGINGstagingProtected si branche release protégée.
AWS_ACCESS_KEY_ID_PRODproductionMasked + protected + environment scoped.
TF_VAR_db_passwordSelon envSecret manager préférable.
TF_VAR_instance_typeSelon envNon secret, mais contrôlé.
Exemple de variables par env
# dev.tfvars
                            environment   = "dev"
                            instance_type = "t3.micro"
                            min_capacity  = 1
                            max_capacity  = 2

                            # staging.tfvars
                            environment   = "staging"
                            instance_type = "t3.small"
                            min_capacity  = 1
                            max_capacity  = 3

                            # prod.tfvars
                            environment   = "prod"
                            instance_type = "t3.medium"
                            min_capacity  = 2
                            max_capacity  = 8
Diagramme secrets
GitLab variables
                            │
                            ├── DEV credentials
                            │     └── accessibles jobs dev
                            │
                            ├── STAGING credentials
                            │     └── accessibles jobs staging
                            │
                            └── PROD credentials
                            ├── masked
                            ├── protected
                            ├── scoped production
                            └── utilisables uniquement par runner protégé
Règles de sécurité
RèglePourquoi
Pas de secrets dans GitÉvite fuite durable dans l’historique.
Variables maskedÉvite affichage dans logs.
Variables protectedBloque l’accès depuis branches non protégées.
Scope environnementÉvite qu’un job dev lise un secret prod.
Rotation régulièreRéduit l’impact en cas de fuite.
Moindre privilègeUn credential dev ne doit jamais pouvoir agir sur prod.
Attention : TF_VAR_* est pratique, mais peut finir dans le state selon l’usage. Pour les secrets, privilégier Vault ou le secret manager cloud.
State Terraform séparé par environnement

Chaque environnement doit avoir son propre state. Mélanger dev, staging et production dans un même state augmente fortement le risque d’incident et rend les plans difficiles à relire.

Backend keys recommandées
# Dev
                            key = "dev/network/terraform.tfstate"
                            key = "dev/app/terraform.tfstate"
                            key = "dev/data/terraform.tfstate"

                            # Staging
                            key = "staging/network/terraform.tfstate"
                            key = "staging/app/terraform.tfstate"
                            key = "staging/data/terraform.tfstate"

                            # Production
                            key = "prod/network/terraform.tfstate"
                            key = "prod/app/terraform.tfstate"
                            key = "prod/data/terraform.tfstate"
Pourquoi découper aussi par domaine ?
DomaineRaison
networkChange rarement, impact fort.
appChange plus souvent, impact applicatif.
dataTrès sensible, protections renforcées.
monitoringPeut évoluer sans toucher au compute.
securityIAM et règles critiques à isoler.
Mauvais vs bon modèle
Mauvais :
                            state-global.tfstate
                            ├── dev
                            ├── staging
                            ├── prod
                            ├── network
                            ├── app
                            └── data

                            Bon :
                            prod/network/terraform.tfstate
                            prod/app/terraform.tfstate
                            prod/data/terraform.tfstate

                            staging/network/terraform.tfstate
                            staging/app/terraform.tfstate
                            staging/data/terraform.tfstate
Remote state entre environnements

Éviter autant que possible que dev lise prod. Si un state doit lire un autre state, le couplage doit être volontaire, documenté et limité à des outputs non sensibles.

data "terraform_remote_state" "network" {
                            backend = "s3"

                            config = {
                            bucket = "company-terraform-state-prod"
                            key    = "prod/network/terraform.tfstate"
                            region = "eu-west-3"
                            }
                            }
Risque : un mauvais backend ou une mauvaise key peut faire pointer un job staging vers un state prod. Toujours afficher l’environnement ciblé dans les logs du pipeline.
Approvals et gouvernance par environnement

Les approvals permettent d’adapter le niveau de contrôle au risque. La production exige un niveau de validation plus fort que dev ou staging.

Politique d’approbation
EnvQui valide ?Quand ?
DevDéveloppeur ou DevOps responsable.Si changement non sensible.
StagingDevOps + tech lead si impact significatif.Avant validation release.
PreprodTech lead, QA, DevOps.Avant répétition prod.
ProdDevOps senior, responsable plateforme, owner métier si nécessaire.Avant apply.
Prod critiqueDouble approval + fenêtre de changement.Changement réseau, DB, IAM, sécurité.
Exemple de règles pratiques
  • Changement d’instance type en dev : validation légère.
  • Ouverture de port en staging : review sécurité.
  • Modification IAM prod : approval obligatoire.
  • Modification database prod : fenêtre de changement + rollback.
  • Suppression/recréation prod : justification écrite obligatoire.
Flux approval production
Merge Request
                            │
                            ▼
                            Pipeline plan production
                            │
                            ▼
                            Plan lisible en artifact
                            │
                            ▼
                            Review technique
                            ├── ressources créées
                            ├── ressources modifiées
                            ├── destroy / replace
                            ├── sécurité
                            └── rollback
                            │
                            ▼
                            Approval
                            │
                            ▼
                            Job apply manuel
                            │
                            ▼
                            Post-checks
Critères Go / No-Go
CritèreGoNo-Go
PlanCompris, attendu, relu.Destroy inexpliqué.
RollbackProcédure claire.Aucune mitigation.
MonitoringAlertes et métriques prêtes.Impact invisible.
FenêtreMoment acceptable.Pic trafic ou période critique.
SécuritéScan OK ou risque accepté.Secret exposé ou IAM trop large.
Bonne gouvernance : les approvals ne doivent pas être bureaucratiques, ils doivent empêcher les changements dangereux non compris.
Promotion dev → staging → production

Une bonne stratégie ne consiste pas à bricoler directement en production. Le changement doit progresser de dev vers staging, puis vers production, avec validation à chaque étape.

Flux de promotion
Feature branch
                            │
                            ├── fmt / validate / plan dev
                            │
                            ▼
                            Merge Request
                            │
                            ├── review code
                            ├── scan sécurité
                            └── review plan
                            │
                            ▼
                            Dev apply
                            │
                            ▼
                            Staging apply
                            │
                            ├── tests fonctionnels
                            ├── tests infra
                            ├── smoke tests
                            └── métriques
                            │
                            ▼
                            Production plan
                            │
                            ▼
                            Approval
                            │
                            ▼
                            Production apply
                            │
                            ▼
                            Post-checks
Pourquoi promouvoir progressivement ?
BénéficeExplication
Détection précoceLes erreurs apparaissent avant la production.
Plan plus fiableLe changement a déjà été observé ailleurs.
Confiance équipeMoins de surprise au moment du prod apply.
Rollback préparéLes impacts sont mieux compris.
Exemple de stratégie de branches
feature/network-private-subnets
                            -> plan dev

                            develop
                            -> apply dev

                            release/2026-04-network
                            -> apply staging

                            main
                            -> plan production
                            -> approval
                            -> apply production
Artefacts utiles à chaque étape
ArtefactUtilité
Plan Terraform lisibleReview humaine.
Plan binaireApply exact du plan généré.
Rapport scan sécuritéPreuve de contrôle IaC.
Log de déploiementAudit et diagnostic.
Résultat post-checkValidation santé après changement.
Attention : staging doit ressembler suffisamment à prod. Un staging trop différent valide peu de choses.
Données par environnement

La séparation des données est aussi importante que la séparation de l’infrastructure. Les données de production ne doivent pas être copiées en dev sans anonymisation et contrôle d’accès.

Politique de données
EnvDonnées recommandéesRisques
Dev localFixtures, données synthétiques.Faible si pas de données réelles.
Dev partagéDonnées anonymisées ou minimales.Fuite si données réelles.
StagingSnapshot anonymisé représentatif.Fausse validation si données trop petites.
PreprodDonnées proches prod mais anonymisées.Conformité, confidentialité.
ProdDonnées réelles.Impact client, légal, business.
Anonymisation : exemples
email:
                            john.smith@example.com -> user_12345@example.test

                            phone:
                            +33612345678 -> +33000000000

                            name:
                            John Smith -> User 12345

                            address:
                            10 Real Street -> 1 Test Street

                            free text:
                            supprimer ou remplacer si contient données personnelles
Flux de données sécurisé
Production database
                            │
                            ▼
                            Export contrôlé
                            │
                            ▼
                            Anonymisation / masking
                            │
                            ▼
                            Validation sécurité
                            │
                            ▼
                            Import staging
                            │
                            ▼
                            Tests fonctionnels et performance
Règles professionnelles
Pas de dump prod brut en localRisque majeur de fuite.
Snapshots chiffrésProtection pendant transfert et stockage.
Accès limitéSeules les personnes autorisées manipulent les exports.
Durée de vie limitéeSupprimer les exports temporaires.
TraçabilitéSavoir qui a extrait, transformé, importé.
Point critique : les environnements non-prod sont souvent moins protégés. Ne jamais y mettre des données production brutes.
Incidents classiques liés aux environnements
Scénarios réels
IncidentCausePrévention
Apply prod depuis feature branchVariables prod non protégées.Protected variables + protected branches.
State staging pointe vers prodBackend key mal configurée.Backend explicite + logs d’environnement.
Database prod utilisée en stagingVariable DB host incorrecte.Secrets scopés + tests de garde-fou.
Runner dev possède droits prodIAM trop large.Runner dédié + rôle cloud dédié.
Staging trop différent de prodInfra sous-dimensionnée ou config divergente.Parité raisonnable sur composants critiques.
Données réelles en devDump prod non anonymisé.Process d’anonymisation obligatoire.
Réaction en cas d’erreur d’environnement
Erreur détectée
                            │
                            ▼
                            Stopper pipeline si encore actif
                            │
                            ▼
                            Identifier environnement réellement touché
                            │
                            ├── state utilisé
                            ├── credentials utilisés
                            ├── backend key
                            ├── branch / commit
                            └── runner
                            │
                            ▼
                            Évaluer impact
                            ├── ressources modifiées
                            ├── données touchées
                            ├── sécurité
                            └── disponibilité
                            │
                            ▼
                            Mitigation / rollback
                            │
                            ▼
                            Postmortem et correction garde-fous
Garde-fou simple dans pipeline
echo "Target environment: $CI_ENVIRONMENT_NAME"
                            echo "Terraform root: $TF_ROOT"
                            echo "Backend key: $TF_STATE_KEY"

                            if [ "$CI_ENVIRONMENT_NAME" = "production" ] && [ "$CI_COMMIT_BRANCH" != "main" ]; then
                            echo "Production deploy is only allowed from main."
                            exit 1
                            fi
Bon réflexe : faire afficher clairement l’environnement ciblé avant tout plan/apply. Cela évite beaucoup d’erreurs humaines.
Anti-patterns de gestion des environnements
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
Mêmes credentials partoutUn job dev peut modifier prod.Credentials dédiés par environnement.
Un seul state globalBlast radius énorme et risque dev/prod.State séparé par env et domaine.
Variables prod globalesAccessibles depuis mauvaises branches/jobs.Variables masked, protected, scoped.
Staging symboliqueNe valide pas les vrais risques prod.Staging proche prod sur composants critiques.
Données prod brutes en devRisque de fuite et non-conformité.Données synthétiques ou anonymisées.
Apply prod automatiqueAucun contrôle humain sur changement critique.Apply manuel, approval, environnement protégé.
Branches non protégéesMerge ou deploy non contrôlé.Protected branches + MR obligatoire.
Pas de convention de nommageConfusion entre ressources dev/staging/prod.Préfixe projet-environnement-composant.
Mauvais modèle
Pipeline unique
                            │
                            ├── mêmes variables
                            ├── mêmes credentials
                            ├── même state
                            ├── mêmes runners
                            └── env choisi manuellement
Résultat : erreur humaine presque inévitable à moyen terme.
Bon modèle
Pipelines contrôlés
                            │
                            ├── variables par environnement
                            ├── credentials par environnement
                            ├── states séparés
                            ├── runners protégés
                            ├── branches protégées
                            └── approvals selon criticité
Résultat : vitesse en dev, contrôle en staging, sécurité en production.
Checklist professionnelle de séparation des environnements
Checklist structure
PointValidation attendue
BranchesMapping clair : feature/dev, release/staging, main/prod.
VariablesVariables séparées et scopées par environnement.
CredentialsCredentials cloud distincts par environnement.
StateState Terraform séparé par env et domaine critique.
RunnersRunner prod protégé, taggé et limité.
NommageRessources préfixées par projet + environnement.
DonnéesPas de données prod brutes hors prod.
MonitoringStaging/prod ont des checks adaptés.
Checklist production
QuestionPourquoi
Le job prod tourne-t-il uniquement depuis main ?Empêcher deploy arbitraire.
Les variables prod sont-elles protected ?Bloquer accès depuis branches non protégées.
L’environnement GitLab production est-il protégé ?Limiter qui peut cliquer apply.
Le state prod est-il isolé ?Éviter mélange avec dev/staging.
Le plan indique-t-il clairement la cible ?Éviter erreur d’environnement.
Le rollback est-il défini ?Réagir vite en cas de mauvais changement.
Les données non-prod sont-elles anonymisées ?Limiter risque légal et sécurité.
Définition d’une bonne séparation : chaque environnement a ses propres droits, variables, state, données, runners et règles de promotion.
Mini-cheat-sheet
feature/*  -> dev / review
                            develop    -> dev partagé
                            release/*  -> staging
                            main       -> production

                            dev:
                            apply rapide, droits limités

                            staging:
                            plan + review + tests

                            prod:
                            plan archivé + approval + apply manuel + post-checks
2.3 Secrets & sécurité CI : variables, OIDC, IAM et moindre privilège
Pourquoi les secrets CI/CD sont critiques

Un pipeline CI/CD infrastructure peut créer, modifier ou supprimer des ressources cloud. Les secrets qu’il utilise — clés cloud, tokens API, mots de passe, certificats, clés SSH, tokens GitLab, credentials registry — doivent être protégés comme des accès production.

Une fuite de secret dans une pipeline peut donner à un attaquant la capacité de lire un state Terraform, modifier une infrastructure, pousser une image, accéder à une base de données ou supprimer des ressources.

Règle absolue : un secret ne doit jamais être stocké en clair dans Git, affiché dans les logs CI, ni partagé entre dev, staging et production sans isolation.
Familles de secrets
SecretExempleRisque si fuite
Cloud credentialsAWS, Azure, GCP, Hetzner.Contrôle infrastructure.
Terraform backendAccès bucket state, GitLab state, Terraform Cloud token.Lecture/modification du state.
RegistryDocker registry, GitLab registry, ECR.Push d’images compromises.
SSH / deploy keyClé privée serveur ou repo.Accès serveur ou code source.
DatabaseMot de passe PostgreSQL/MySQL/Redis.Lecture ou modification de données.
API tokenCloudflare, Datadog, GitLab, Slack, Sentry.Modification DNS, monitoring, notifications, projets.
Chaîne de sécurité idéale
Développeur
                            │
                            ▼
                            Merge Request
                            │
                            ├── pas d'accès secret prod
                            ├── scan secret detection
                            └── plan limité
                            │
                            ▼
                            Branche protégée
                            │
                            ▼
                            Runner protégé
                            │
                            ├── variables masked/protected/scoped
                            ├── credentials courts ou OIDC
                            ├── IAM least privilege
                            └── logs contrôlés
                            │
                            ▼
                            Terraform / Déploiement
                            │
                            ├── remote state sécurisé
                            ├── pas de secret affiché
                            └── audit des actions cloud
Objectifs professionnels
Réduire l’expositionSecrets disponibles uniquement au moment et au job nécessaires.
Limiter le blast radiusUn secret dev ne doit pas agir sur prod.
Éviter le secret statiquePréférer credentials temporaires, OIDC, STS, Vault.
Tracer les usagesAudit cloud et GitLab pour savoir qui a fait quoi.
Permettre la révocationRotation documentée et rapide en cas de fuite.
Niveau pro : un pipeline sécurisé ne cache pas seulement les secrets : il limite leur durée de vie, leur portée, leurs droits et leur exposition dans les logs.
Variables GitLab : masked, protected, scoped

GitLab CI/CD permet de stocker des variables utilisées par les jobs. Pour les secrets, il faut utiliser les options de protection adaptées : masquage dans les logs, accès limité aux branches protégées et scope par environnement.

Options importantes
OptionRôleÀ utiliser pour
MaskedMasque la valeur dans les logs.Tokens, clés, mots de passe.
ProtectedDisponible seulement pour branches/tags protégés.Credentials production.
Environment scopeLimite une variable à un environnement GitLab.Dev, staging, production.
File variableCrée un fichier temporaire avec le contenu secret.Kubeconfig, certificat, clé privée.
Group variablePartage une variable sur plusieurs projets.Standards d’équipe.
Project variableLimite au projet courant.Secret spécifique applicatif.
Exemples de noms
# Dev
                            AWS_ACCESS_KEY_ID_DEV
                            AWS_SECRET_ACCESS_KEY_DEV

                            # Staging
                            AWS_ACCESS_KEY_ID_STAGING
                            AWS_SECRET_ACCESS_KEY_STAGING

                            # Production
                            AWS_ACCESS_KEY_ID_PROD
                            AWS_SECRET_ACCESS_KEY_PROD

                            # Terraform variables
                            TF_VAR_project
                            TF_VAR_environment
                            TF_VAR_db_password
Bon usage dans un job
terraform_plan_prod:
                            stage: plan
                            environment:
                            name: production
                            script:
                            - terraform init
                            - terraform plan -var-file="prod.tfvars"
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
Mauvais usage
# Mauvais : secret dans le YAML
                            variables:
                            AWS_SECRET_ACCESS_KEY: "my-secret-value"

                            # Mauvais : affichage dans les logs
                            script:
                            - echo "$AWS_SECRET_ACCESS_KEY"
Règles concrètes
Pas de secret dans .gitlab-ci.ymlLe YAML est versionné dans Git.
Pas de secret dans *.tfvars commitéRisque de fuite durable.
Pas de secret dans echoLes logs CI sont consultables et persistants.
Variables prod protectedAccès seulement depuis branches/tags protégés.
Variables prod scopedAccès seulement pour l’environnement production.
Attention : “masked” réduit l’exposition dans les logs, mais ne remplace pas le moindre privilège, la rotation et l’isolation par environnement.
Scopes : limiter où un secret peut être utilisé

Un secret doit être disponible uniquement dans les contextes nécessaires. Plus son scope est large, plus le risque est grand. Une variable production globale est dangereuse : elle peut être utilisée par erreur par un job qui ne devrait jamais agir sur prod.

Mapping recommandé
SecretScopeDisponible pour
AWS_ACCESS_KEY_ID_DEVdevelopmentJobs dev uniquement.
AWS_ACCESS_KEY_ID_STAGINGstagingJobs staging uniquement.
AWS_ACCESS_KEY_ID_PRODproductionJobs production uniquement.
GITLAB_TOKEN_READONLYglobal ou projetLecture API limitée.
REGISTRY_PUSH_TOKENbuildJobs build/publish.
Séparation branche / environnement
feature/*
                            │
                            └── pas de secrets prod

                            develop
                            │
                            └── secrets dev

                            release/*
                            │
                            └── secrets staging

                            main
                            │
                            └── secrets production
                            ├── masked
                            ├── protected
                            └── environment scoped
Garde-fou dans le pipeline
check_environment_safety:
                            stage: validate
                            script:
                            - echo "Branch: $CI_COMMIT_BRANCH"
                            - echo "Environment: $CI_ENVIRONMENT_NAME"
                            - |
                            if [ "$CI_ENVIRONMENT_NAME" = "production" ] && [ "$CI_COMMIT_BRANCH" != "main" ]; then
                            echo "Production jobs are only allowed from main."
                            exit 1
                            fi
Erreur classique
Variable globale :
                            AWS_SECRET_ACCESS_KEY_PROD

                            Disponible dans :
                            ├── feature/*
                            ├── develop
                            ├── release/*
                            └── main

                            Résultat :
                            une MR ou un job non protégé peut exposer ou utiliser le secret prod.
Règle : les credentials production ne doivent jamais être globaux. Ils doivent être protégés, scopés et accessibles uniquement depuis le flux production.
OIDC : remplacer les clés statiques par des credentials temporaires

OIDC permet à GitLab CI/CD de demander un jeton d’identité temporaire, puis de l’échanger contre des credentials cloud temporaires. Cela évite de stocker des clés cloud longues durées dans GitLab.

Pourquoi OIDC est préférable
ApprocheAvantageRisque
Clé statiqueSimple à configurer.Fuite durable si compromise.
OIDCCredentials temporaires, contextuels, révocables.Configuration initiale plus avancée.
Vault dynamiqueSecrets courts et centralisés.Nécessite plateforme Vault.
Flux OIDC
GitLab job
                            │
                            ▼
                            Demande un ID token OIDC
                            │
                            ▼
                            Cloud IAM vérifie :
                            ├── projet GitLab
                            ├── branche
                            ├── environnement
                            ├── audience
                            └── claims autorisés
                            │
                            ▼
                            Cloud émet credentials temporaires
                            │
                            ▼
                            Terraform plan/apply
                            │
                            ▼
                            Credentials expirent automatiquement
Bonne pratique : OIDC limite fortement l’impact d’une fuite, car il évite les clés longues durées stockées dans la CI.
Exemple conceptuel AWS STS
assume_role_with_web_identity:
                            stage: validate
                            id_tokens:
                            GITLAB_OIDC_TOKEN:
                            aud: https://gitlab.com
                            script:
                            - echo "Exchange OIDC token for temporary cloud credentials"
                            - echo "Run terraform with short-lived credentials"
Contrôles à mettre dans la trust policy
ConditionBut
Projet GitLab exactEmpêcher un autre projet d’assumer le rôle.
Branche protégéeLimiter la production à main ou tags release.
EnvironnementDifférencier dev, staging, prod.
AudienceEmpêcher réutilisation du token ailleurs.
Durée courteLimiter la fenêtre d’exploitation.
Attention : OIDC n’autorise pas à donner des droits larges. Il doit être combiné avec IAM least privilege.
IAM et moindre privilège

Le compte ou rôle utilisé par la CI/CD ne doit avoir que les permissions nécessaires. Une erreur de pipeline ne doit pas pouvoir supprimer tout le compte cloud, lire tous les secrets ou modifier tous les environnements.

Stratégie de rôles
RôleDroitsUsage
plan-devLecture + droits limités dev.Plan et tests dev.
apply-devÉcriture dev limitée.Apply dev.
plan-prodLecture production.Générer plan production.
apply-prodÉcriture production limitée aux ressources nécessaires.Apply manuel protégé.
break-glassDroits élevés temporaires.Incident majeur, audit obligatoire.
Least privilege : principes
  • Séparer dev, staging et production.
  • Séparer plan et apply si possible.
  • Limiter les actions aux services réellement utilisés.
  • Limiter les ressources par nom, tags, région ou compte.
  • Éviter les wildcards * sauf justification.
  • Auditer régulièrement les permissions inutilisées.
IAM trop large : mauvais exemple
{
                            "Effect": "Allow",
                            "Action": "*",
                            "Resource": "*"
                            }
Approche plus contrôlée
{
                            "Effect": "Allow",
                            "Action": [
                            "ec2:Describe*",
                            "ec2:CreateTags",
                            "elasticloadbalancing:Describe*",
                            "rds:Describe*"
                            ],
                            "Resource": "*"
                            }
Blast radius
Credential CI compromis
                            │
                            ▼
                            Si IAM large :
                            └── impact compte cloud complet

                            Si IAM limité :
                            ├── actions limitées
                            ├── ressources limitées
                            ├── environnement limité
                            └── durée limitée si OIDC/STS
Règle : un rôle CI/CD production ne doit jamais être administrateur global par confort. C’est une dette de sécurité majeure.
Vault, Secret Manager et rotation

Les variables GitLab sont utiles, mais pour des organisations plus matures, un gestionnaire de secrets centralisé permet de contrôler la rotation, les accès, l’audit, les credentials dynamiques et la révocation.

Solutions fréquentes
SolutionUsagePoints forts
HashiCorp VaultSecrets centralisés, credentials dynamiques.Très puissant, multi-cloud, audit.
AWS Secrets ManagerSecrets applicatifs et rotation AWS.Intégration AWS native.
AWS SSM Parameter StoreParamètres et secrets simples.Simple, économique, IAM natif.
Azure Key VaultSecrets, certificats, clés Azure.Intégration Azure.
GCP Secret ManagerSecrets GCP versionnés.Intégration IAM GCP.
GitLab CI variablesSecrets pipeline simples.Pratique, intégré CI/CD.
Quand sortir de GitLab variables ?
  • Beaucoup de secrets ou beaucoup de projets.
  • Besoin d’audit centralisé.
  • Besoin de rotation automatique.
  • Besoin de credentials dynamiques et temporaires.
  • Exigences conformité ou séparation forte des responsabilités.
Flux Secret Manager
GitLab Runner
                            │
                            ├── s'authentifie via OIDC / rôle court
                            │
                            ▼
                            Secret Manager / Vault
                            │
                            ├── vérifie identité
                            ├── vérifie policy
                            ├── journalise l'accès
                            └── retourne secret ou credential temporaire
                            │
                            ▼
                            Job CI/CD
                            │
                            └── utilise le secret sans le stocker dans Git
Rotation
SecretFréquence indicativeDéclencheur urgent
Cloud access key30 à 90 jours si statique.Suspicion de fuite.
API tokenSelon criticité.Log exposé ou repo compromis.
Database passwordPlanifiée et testée.Fuite, départ collaborateur, incident.
SSH keyÀ éviter en CI si possible.Serveur ou runner compromis.
Bonne maturité : le meilleur secret CI est celui qui n’est jamais stocké longtemps et qui expire automatiquement.
Logs CI : surface d’exposition majeure

Les logs CI sont souvent conservés, partagés, consultables par plusieurs personnes et parfois exportés vers des systèmes externes. Ils ne doivent jamais contenir de secrets.

Mauvais exemples
# Mauvais : affiche le secret
                            script:
                            - echo "$AWS_SECRET_ACCESS_KEY"

                            # Mauvais : debug shell trop bavard
                            script:
                            - set -x
                            - terraform plan

                            # Mauvais : dump d'environnement
                            script:
                            - env
                            - printenv
Règle : ne jamais afficher l’environnement complet dans une pipeline qui contient des secrets.
Meilleure approche
script:
                            - echo "Terraform plan started"
                            - terraform plan -var-file="prod.tfvars"
                            - echo "Terraform plan completed"
Risques logs
RisqueExemplePrévention
Echo secretecho $TOKENInterdire affichage secrets.
Mode debugset -xDésactiver autour des commandes sensibles.
Terraform outputOutput contenant mot de passe.sensitive = true, outputs minimaux.
Erreur outilStack trace imprimant config.Tester outils, filtrer logs, limiter secrets.
Artifact involontaireArchive contenant .env ou state.Artifacts explicitement listés.
Commande de debug plus sûre
# Vérifier seulement la présence
                            if [ -z "$AWS_ACCESS_KEY_ID" ]; then
                            echo "AWS_ACCESS_KEY_ID is missing"
                            exit 1
                            else
                            echo "AWS_ACCESS_KEY_ID is present"
                            fi
Attention : même un secret masqué peut fuiter s’il est transformé, encodé, découpé ou affiché dans un format inattendu.
Terraform, state et secrets

Terraform peut manipuler des valeurs sensibles, mais il faut comprendre une limite majeure : sensitive = true masque l’affichage, mais ne garantit pas que la valeur soit absente du state. Le state doit donc être protégé.

Variable sensible
variable "database_password" {
                            description = "Database password."
                            type        = string
                            sensitive   = true
                            }
Output sensible
output "database_password" {
                            value     = var.database_password
                            sensitive = true
                            }
Attention : éviter d’exposer un mot de passe en output. Même marqué sensitive, c’est souvent un mauvais design.
Ce qu’il faut protéger
Remote stateChiffrement, IAM strict, audit, versioning.
Artifacts planNe pas archiver des plans contenant des secrets non maîtrisés.
tfvarsNe pas commiter les fichiers contenant secrets.
OutputsLimiter au strict nécessaire.
Flux recommandé
Secret Manager
                            │
                            ▼
                            Application runtime
                            │
                            └── récupère secret au démarrage
                            ou via injection sécurisée

                            Terraform
                            │
                            ├── crée l'infrastructure
                            ├── crée éventuellement la référence au secret
                            └── évite de manipuler la valeur brute
Exemple : référence plutôt que valeur
variable "database_password_secret_name" {
                            description = "Name of the secret storing DB password."
                            type        = string
                            }

                            # Terraform configure l'application avec le nom du secret,
                            # pas forcément avec sa valeur brute.
Checklist Terraform secrets
QuestionRéponse attendue
Le secret est-il dans Git ?Non.
Le secret apparaît-il dans plan/logs ?Non.
Le state est-il chiffré et protégé ?Oui.
Le secret peut-il être rotaté ?Oui.
Terraform a-t-il vraiment besoin de la valeur brute ?À éviter si possible.
Bonne pratique : Terraform doit créer les contenants, permissions et références. L’application doit récupérer les secrets par mécanisme sécurisé au runtime si possible.
Incidents de secrets : détection, réponse, rotation
Scénarios classiques
IncidentCauseImpact possible
Secret commité dans Git.env, tfvars, clé privée ajoutée par erreur.Fuite durable dans historique.
Secret affiché dans logsecho, env, debug shell.Consultation par utilisateurs GitLab.
Runner compromisRunner partagé ou mal isolé.Vol de variables et tokens.
Clé cloud trop largeIAM admin dans CI.Contrôle complet du compte cloud.
Artifact sensiblePlan/state/env archivé par erreur.Fuite via téléchargement artifact.
Réponse incident
Fuite suspectée
                            │
                            ▼
                            Stopper exposition
                            ├── supprimer variable/log/artifact si possible
                            ├── bloquer pipeline compromis
                            └── désactiver credential
                            │
                            ▼
                            Rotation
                            ├── créer nouveau secret
                            ├── mettre à jour CI/CD
                            ├── invalider ancien secret
                            └── vérifier services
                            │
                            ▼
                            Investigation
                            ├── qui a eu accès ?
                            ├── depuis quand ?
                            ├── quelles actions cloud ?
                            └── quels logs/audits ?
                            │
                            ▼
                            Postmortem et prévention
Runbook de rotation rapide
1. Identifier le secret exposé.
                            2. Déterminer son périmètre : dev, staging, prod.
                            3. Révoquer ou désactiver l’ancien secret.
                            4. Créer un nouveau secret avec droits minimaux.
                            5. Mettre à jour GitLab/Vault/Secret Manager.
                            6. Relancer pipeline de validation.
                            7. Vérifier que les services fonctionnent.
                            8. Auditer les logs d’utilisation.
                            9. Nettoyer logs/artifacts si possible.
                            10. Documenter cause et prévention.
Priorité selon criticité
Secret exposéPrioritéAction
Credential prod adminCritiqueRévocation immédiate + audit cloud.
DB prod passwordCritiqueRotation + analyse accès.
Token stagingÉlevéeRotation + vérifier absence prod.
Token lecture non-prodMoyenneRotation planifiée rapide.
Règle : un secret exposé doit être considéré compromis. Le supprimer du log ou du repo ne suffit pas : il faut le révoquer ou le rotater.
Anti-patterns secrets & sécurité CI
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
Secret dans GitFuite durable dans l’historique.Variables GitLab, Vault, Secret Manager.
Variables prod globalesAccessibles par jobs non-prod ou branches non protégées.Masked + protected + environment scoped.
IAM admin en CIUn pipeline compromis contrôle tout.Rôles par environnement et moindre privilège.
Clés statiques longues duréesFuite exploitable longtemps.OIDC, STS, credentials temporaires.
echo $SECRETSecret exposé dans logs.Tester présence sans afficher valeur.
set -x partoutCommandes et variables sensibles affichées.Debug ciblé, désactivé autour secrets.
Artifacts trop largesArchive de fichiers sensibles.Artifacts explicitement listés et contrôlés.
Pas de rotationSecret ancien, oublié, difficile à révoquer.Rotation planifiée et runbook testé.
Mauvais modèle
Pipeline CI
                            │
                            ├── clé cloud statique
                            ├── droits admin
                            ├── variable globale
                            ├── logs verbeux
                            ├── pas de rotation
                            └── pas d'audit
Résultat : un simple bug de pipeline ou une MR malveillante peut devenir un incident de sécurité majeur.
Modèle professionnel
Pipeline CI sécurisé
                            │
                            ├── OIDC ou credentials courts
                            ├── IAM least privilege
                            ├── variables protected/scoped
                            ├── runner protégé
                            ├── logs sobres
                            ├── rotation documentée
                            └── audit activé
Résultat : le pipeline peut agir efficacement tout en limitant fortement le blast radius en cas d’erreur ou de compromission.
Checklist professionnelle secrets & sécurité CI
Checklist GitLab
PointValidation attendue
MaskedLes secrets sont masqués dans les logs.
ProtectedLes secrets prod sont limités aux branches/tags protégés.
Environment scopedLes variables prod ne sont disponibles qu’en production.
Runner protégéLes jobs prod tournent sur un runner contrôlé.
Artifacts contrôlésAucun .env, .tfstate ou secret dans les artifacts.
Secret detectionScan activé sur MR et branches principales.
Logs sobresPas de env, printenv, echo $SECRET.
Checklist IAM
Rôle dédié CIPas de clé personnelle dans la pipeline.
Moindre privilègeActions et ressources limitées.
Séparation envDev, staging, prod ont des rôles différents.
Credentials courtsOIDC/STS si possible.
AuditCloudTrail/audit logs activés.
RotationProcédure documentée et testée.
Checklist Terraform
QuestionRéponse attendue
Un secret est-il commité dans tfvars ?Non.
Le state peut-il contenir des secrets ?Oui, donc il est chiffré et protégé.
Les outputs exposent-ils des secrets ?Non, sauf cas exceptionnel marqué sensitive.
Le plan affiche-t-il des valeurs sensibles ?Non.
Le backend state est-il restreint ?Oui, IAM strict et audit.
Terraform a-t-il besoin de la valeur brute ?À éviter quand une référence secret suffit.
Définition d’une CI sécurisée : secrets non stockés en clair, droits limités, credentials courts, logs propres, state protégé, rotation possible et audit activé.
Mini-cheat-sheet
# À faire
                            - masked variables
                            - protected variables
                            - environment scopes
                            - runner protégé
                            - IAM least privilege
                            - OIDC / credentials temporaires
                            - secret detection
                            - rotation documentée

                            # À éviter
                            - secrets dans Git
                            - echo $SECRET
                            - env / printenv en CI
                            - IAM admin
                            - variables prod globales
                            - artifacts contenant .tfstate ou .env
2.4 Déploiement infra : changement, revue, fenêtre, apply et vérification
Déployer de l’infrastructure n’est pas “juste cliquer Apply”

Un déploiement infrastructure modifie la fondation sur laquelle repose l’application : réseau, sécurité, compute, base de données, DNS, certificats, IAM, monitoring ou stockage. Une erreur peut provoquer une indisponibilité, une faille de sécurité ou une perte de données.

Le workflow professionnel consiste à préparer le changement, générer un plan, le faire relire, choisir une fenêtre adaptée, appliquer de façon contrôlée, puis vérifier l’état réel de la production.

Objectif : rendre chaque changement infra prévisible, relisible, traçable, approuvé, vérifiable et réversible ou au minimum mitigable.
Les 6 étapes d’un changement infra
ÉtapeButSortie attendue
PréparationComprendre besoin, impact, risque.Ticket ou change request clair.
DéveloppementModifier Terraform ou pipeline.Branche Git dédiée.
Validationfmt, validate, security, plan.Pipeline vert + plan lisible.
ReviewRelire le plan et les risques.Approval ou corrections.
ApplyAppliquer dans le bon contexte.Infra modifiée proprement.
VérificationContrôler cloud, app, logs, métriques.Validation post-changement.
Diagramme global
Besoin métier / technique
                            │
                            ▼
                            Change request
                            │
                            ├── impact
                            ├── risque
                            ├── rollback
                            └── fenêtre éventuelle
                            │
                            ▼
                            Branche Git
                            │
                            ▼
                            Merge Request
                            │
                            ├── terraform fmt
                            ├── terraform validate
                            ├── security scan
                            └── terraform plan
                            │
                            ▼
                            Review du plan
                            │
                            ▼
                            Approval
                            │
                            ▼
                            Apply contrôlé
                            │
                            ▼
                            Vérifications post-apply
                            ├── cloud
                            ├── application
                            ├── logs
                            ├── métriques
                            └── alerting
                            │
                            ▼
                            Clôture / documentation
Différence entre app deploy et infra deploy
TypeRollbackRisque
Déploiement applicatifSouvent revenir à l’image/version précédente.Bug applicatif, régression fonctionnelle.
Déploiement infraParfois revenir au commit précédent, parfois mitigation.Réseau, sécurité, données, disponibilité.
Attention : un rollback infra peut lui-même contenir des suppressions ou recréations. Il doit donc être planifié et relu comme un changement normal.
Workflow propre de déploiement infrastructure
Workflow standard production
  1. Créer une demande de changement ou ticket technique.
  2. Décrire le besoin, le périmètre et le risque.
  3. Créer une branche Git dédiée.
  4. Modifier le code Terraform ou la configuration CI/CD.
  5. Lancer terraform fmt, validate, scan sécurité et plan.
  6. Relire le plan en merge request.
  7. Identifier destructions, remplacements, ouvertures réseau, IAM, database.
  8. Obtenir approval selon criticité.
  9. Appliquer dans une fenêtre adaptée.
  10. Vérifier santé cloud, applicative, logs, métriques et alertes.
  11. Documenter résultat, anomalies et suites éventuelles.
Bonne pratique : plus le changement est risqué, plus il doit être petit, isolé et facilement observable.
Pipeline type
MR pipeline
                            │
                            ├── lint
                            ├── validate
                            ├── security
                            └── plan
                            │
                            ▼
                            Review humaine
                            │
                            ▼
                            Merge vers main
                            │
                            ▼
                            Production pipeline
                            │
                            ├── plan final
                            ├── approval
                            ├── apply manuel
                            └── post-checks
Responsabilités
ActeurResponsabilité
AuteurPrépare changement, plan, rollback et documentation.
Reviewer DevOpsRelit Terraform, plan, state, impact et sécurité.
Tech leadValide impact applicatif ou architecture.
SecurityValide IAM, exposition réseau, secrets si nécessaire.
Incident/on-callSurveille après apply si changement critique.
Règle d’équipe : celui qui applique doit comprendre le plan, pas seulement cliquer sur un bouton.
Change request : préparer le changement

Avant de modifier la production, il faut savoir ce qui change, pourquoi, quand, comment vérifier, comment revenir en arrière et qui doit être informé.

Template de change request
Titre :
                            Ajouter un nouveau target group pour l'API publique

                            Objectif :
                            Préparer le routage vers la nouvelle version API.

                            Environnement :
                            production

                            Périmètre :
                            Load balancer, listener rule, target group, health check.

                            Risque :
                            Mauvais routage ou health check incorrect.

                            Plan de validation :
                            - terraform plan relu
                            - health check /health/
                            - test HTTP 200 sur endpoint API
                            - logs 5xx surveillés

                            Rollback / mitigation :
                            - désactiver nouvelle listener rule
                            - revenir au commit précédent
                            - appliquer plan de rollback validé

                            Fenêtre :
                            Hors pic trafic, présence DevOps + backend engineer.
Objectif : rendre le changement compréhensible par quelqu’un qui n’a pas écrit le code.
Classification du risque
NiveauExemplesContrôle
FaibleTags, dashboard, alarme non critique.Review simple.
MoyenAutoscaling, security group interne, compute.Review + staging.
ÉlevéLoad balancer, DNS, IAM, réseau.Approval + fenêtre.
CritiqueDatabase, state, suppression, changement CIDR.Double approval + runbook + présence on-call.
Questions à poser avant de coder
Quel service peut être impacté ?Application, réseau, DB, sécurité, DNS.
Y a-t-il un changement destructif ?Suppression, remplacement, recréation.
Le changement a-t-il été testé en staging ?Oui si possible.
Comment vérifier le succès ?Health checks, métriques, logs, tests.
Comment réduire l’impact si problème ?Rollback, mitigation, feature flag, désactivation.
Erreur fréquente : commencer par coder sans avoir défini la validation et la stratégie de mitigation.
Plan Terraform : l’étape de vérité

Le plan Terraform est le document de décision. Il montre ce qui va être créé, modifié, remplacé ou supprimé. En production, il doit être relu comme un changement réel, pas comme un simple log technique.

Commandes recommandées
terraform fmt -check -recursive
                            terraform validate
                            terraform plan -var-file="prod.tfvars" -out="tfplan"
                            terraform show -no-color tfplan > plan.txt
Lecture du plan
SymboleSignificationRéflexe production
+Création.Vérifier nommage, tags, coût, sécurité.
~Modification en place.Comprendre l’impact runtime.
-/+Remplacement.Analyse obligatoire, risque downtime.
-Suppression.Stop si non explicitement attendu.
Règle : aucun destroy ou replace en production ne doit passer sans justification claire.
Checklist de review du plan
ZoneÀ vérifier
ScopeLe plan touche bien le bon environnement et le bon domaine.
NetworkPas d’ouverture large non prévue, routes cohérentes.
IAMPas de droits trop larges, pas de wildcard inutile.
DatabasePas de remplacement, suppression ou perte backup.
ComputeCapacité, health checks, autoscaling, image/version.
SecretsAucune valeur sensible affichée.
CostPas de ressource coûteuse non prévue.
Diagramme décisionnel
Plan généré
                            │
                            ▼
                            Contient destroy / replace ?
                            │
                            ├── Oui : justification + approval renforcé
                            └── Non
                            │
                            ▼
                            Touche réseau / IAM / DB ?
                            │
                            ├── Oui : review senior / sécurité
                            └── Non
                            │
                            ▼
                            Plan cohérent ?
                            │
                            ├── Oui : apply contrôlé
                            └── Non : correction avant merge
Fenêtre de production

Tous les changements n’exigent pas une fenêtre de production stricte, mais les changements à risque doivent être faits à un moment où l’équipe peut surveiller, réagir et communiquer.

Quand prévoir une fenêtre ?
ChangementFenêtre recommandée ?Pourquoi
Tags ou dashboardNon en général.Impact faible.
Security group interneSelon criticité.Peut couper flux applicatifs.
Load balancer / DNSOui.Impact trafic utilisateur.
IAM productionOui.Peut bloquer application ou pipeline.
DatabaseOui, obligatoire si risque.Données, downtime, performance.
Réseau VPC / routesOui.Blast radius élevé.
Préparation fenêtre
  • Plan validé et archivé.
  • Rollback ou mitigation écrit.
  • Personnes clés disponibles.
  • Monitoring ouvert avant apply.
  • Canal de communication prêt.
  • Pas de changement concurrent critique.
Timeline type
T-30 min
                            ├── vérifier pipeline vert
                            ├── ouvrir dashboards
                            ├── confirmer présence équipe
                            └── annoncer début fenêtre

                            T0
                            ├── déclencher apply
                            └── surveiller logs Terraform

                            T+5 min
                            ├── vérifier cloud resources
                            ├── health checks
                            └── métriques initiales

                            T+15 min
                            ├── vérifier erreurs 5xx
                            ├── vérifier latence
                            └── confirmer absence alertes

                            T+30 min
                            ├── clôturer changement
                            └── documenter résultat
Communication minimale
Début :
                            Changement infra PROD démarré.
                            Périmètre : Load balancer API.
                            Risque : routage HTTP.
                            Rollback : listener rule précédente.

                            Fin :
                            Changement terminé.
                            Health checks OK.
                            5xx stable.
                            Aucune alerte critique.
                            Surveillance prolongée 30 minutes.
Bonne pratique : ne jamais appliquer un changement critique juste avant de quitter l’ordinateur ou sans personne disponible pour surveiller.
Apply contrôlé

L’apply doit exécuter le plan validé, dans le bon environnement, avec le bon state, les bons credentials et les bons garde-fous.

Commande recommandée
terraform plan -out="tfplan" -var-file="prod.tfvars"
                            terraform apply "tfplan"

Appliquer le fichier tfplan évite qu’un plan différent soit recalculé au moment de l’apply.

Job GitLab apply protégé
terraform_apply_prod:
                            stage: apply
                            environment:
                            name: production
                            script:
                            - terraform apply "tfplan"
                            dependencies:
                            - terraform_plan_prod
                            when: manual
                            allow_failure: false
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
                            tags:
                            - terraform
                            - prod
                            - protected
Attention : apply doit être manuel et protégé en production, sauf organisation très mature avec policy-as-code robuste.
Avant de lancer Apply
ContrôleValidation
BrancheLa branche autorisée est utilisée.
EnvironnementProduction/staging/dev clairement affiché.
StateBackend distant et locking actif.
PlanPlan relu, archivé, non obsolète.
CredentialsRôle CI/CD limité et prévu.
MonitoringDashboards ouverts.
RollbackProcédure disponible.
Pendant l’apply
  • Surveiller les ressources modifiées.
  • Ne pas interrompre brutalement sauf nécessité.
  • Noter toute erreur, timeout ou ressource partielle.
  • Ne pas relancer plusieurs applies en parallèle.
  • En cas de lock, comprendre avant de déverrouiller.
Règle : si l’apply échoue partiellement, toujours relancer un plan avant toute correction.
Vérification post-apply

Un apply terminé sans erreur ne prouve pas que la production va bien. Il faut vérifier l’état réel : cloud, application, logs, métriques, alerting et parfois parcours métier.

Ce qu’il faut regarder après apply
ZoneContrôleSignal attendu
CloudRessources créées/modifiées visibles.État healthy / active.
ApplicationHealthcheck HTTP.200 OK ou statut attendu.
LogsErreurs 5xx, exceptions, timeouts.Pas d’anomalie nouvelle.
MetricsCPU, RAM, latence, saturation, erreurs.Stable ou attendu.
DatabaseConnexions, locks, réplication, espace disque.Pas de dégradation.
AlertingAlertes critiques nouvelles.Aucune alerte inattendue.
BusinessLogin, checkout, API critique, batch.Parcours OK.
Commandes exemples
curl -fsS https://example.com/health/
                            curl -fsS https://example.com/api/status/

                            terraform output
                            terraform state list

                            # Exemples Linux
                            journalctl -u app.service -n 100 --no-pager
                            tail -n 100 /var/log/nginx/error.log
Diagramme vérification
Apply terminé
                            │
                            ▼
                            Contrôle cloud
                            │
                            ▼
                            Contrôle applicatif
                            │
                            ├── healthcheck
                            ├── endpoint critique
                            └── parcours métier
                            │
                            ▼
                            Contrôle observabilité
                            ├── logs
                            ├── metrics
                            ├── traces
                            └── alertes
                            │
                            ▼
                            Décision
                            ├── OK : clôture changement
                            └── KO : mitigation / rollback
Post-check GitLab
post_deploy_checks:
                            stage: post_check
                            image: alpine:latest
                            before_script:
                            - apk add --no-cache curl
                            script:
                            - curl -fsS https://example.com/health/
                            - curl -fsS https://example.com/api/status/
                            needs:
                            - terraform_apply_prod
                            rules:
                            - if: '$CI_COMMIT_BRANCH == "main"'
Bonne pratique : automatiser les checks simples, mais garder une surveillance humaine pour les changements à fort impact.
Rollback et mitigation infrastructure

Le rollback infra doit être anticipé avant l’apply. Dans certains cas, revenir au commit précédent suffit. Dans d’autres cas, il faut une mitigation : restaurer un flux réseau, remettre une règle, basculer DNS, désactiver une route ou restaurer un backup.

Rollback possible selon changement
ChangementRollback typiqueAttention
Security groupRestaurer règle précédente.Ne pas rouvrir trop large.
DNSRevenir à l’ancien record.TTL et propagation.
Load balancerRestaurer listener/target group précédent.Health checks.
IAMRestaurer policy précédente.Propagation et permissions.
DatabaseMitigation ou restore backup.Risque data élevé.
StateRestaurer version state si nécessaire.Opération très sensible.
Rollback par revert Git
git revert <commit_id>
                            git push origin main

                            # Pipeline :
                            terraform plan -out=tfplan
                            # Review du plan de rollback
                            terraform apply tfplan
Attention : le plan de rollback doit être relu. Il peut contenir des effets secondaires.
Runbook rollback minimal
Incident post-apply
                            │
                            ▼
                            Déclarer l'incident
                            │
                            ▼
                            Identifier impact
                            ├── utilisateurs
                            ├── services
                            ├── réseau
                            ├── données
                            └── sécurité
                            │
                            ▼
                            Choisir action
                            ├── rollback Git/Terraform
                            ├── hotfix Terraform
                            ├── mitigation manuelle contrôlée
                            └── restore backup
                            │
                            ▼
                            Planifier action
                            │
                            ▼
                            Appliquer correction
                            │
                            ▼
                            Vérifier récupération
                            │
                            ▼
                            Postmortem
Mitigation d’urgence
CasMitigation possible
API inaccessibleRestaurer ancienne listener rule ou target group.
DB inaccessibleRestaurer règle security group précédente.
DNS incorrectRevenir ancien record, réduire TTL si possible.
IAM bloque applicationRestaurer permission minimale nécessaire.
Règle : toute action manuelle d’urgence doit ensuite être reportée dans Terraform pour éviter le drift.
Cas concrets de production
Cas 1 : changement security group DB
ObjectifAutoriser un nouveau service applicatif à joindre PostgreSQL.
RisqueBloquer l’ancien service ou ouvrir DB trop largement.
Plan à relireIngress DB, source security group, port exact.
VérificationConnexion DB depuis nouveau service + logs erreurs DB.
RollbackRestaurer règle précédente.
Cas 2 : ajout autoscaling
ObjectifAdapter capacité au trafic.
RisqueScale trop agressif, coût, instabilité.
Plan à relireMin/max capacity, métriques, cooldown.
VérificationCapacité, CPU, latence, nombre d’instances/tâches.
RollbackRevenir min/max précédents ou désactiver policy.
Cas 3 : changement DNS
ObjectifPointer un domaine vers un nouveau load balancer.
RisqueTrafic vers mauvaise cible, propagation lente.
Plan à relireRecord, zone, TTL, cible.
Vérificationdig, curl, logs load balancer.
RollbackRestaurer ancien record, tenir compte TTL.
Cas 4 : modification RDS
ObjectifAugmenter stockage ou classe instance.
RisqueDowntime, performance, coût, maintenance window.
Plan à relireReplace interdit, backup, multi-AZ, apply immediately.
VérificationConnexions, latence DB, espace disque, locks.
RollbackSouvent non trivial : mitigation ou nouvelle modification.
Point critique : les changements database doivent être traités comme des changements à risque élevé, même s’ils semblent simples dans Terraform.
Anti-patterns du déploiement infrastructure
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
Apply local en productionPas de traçabilité complète, variables locales divergentes.Apply via CI/CD protégé.
Plan non reluDestroy/replace non détecté.Review obligatoire du plan.
Changement énormeImpossible à relire et rollback complexe.Petits changements isolés.
Apply juste avant départPersonne disponible en cas d’incident.Fenêtre avec surveillance.
Pas de monitoringIncident invisible jusqu’au client.Dashboards et alertes avant changement.
Rollback improviséRéaction lente et risquée.Runbook de mitigation avant apply.
Hotfix console non reportéDrift permanent et futurs plans dangereux.Reporter dans Terraform rapidement.
Apply concurrentState lock, incohérence, conflits.Locking + file d’exécution contrôlée.
Mauvais modèle
terraform apply local
                            │
                            ├── pas de MR
                            ├── pas de plan archivé
                            ├── pas d'approval
                            ├── pas de fenêtre
                            ├── pas de monitoring
                            └── rollback improvisé
Résultat : chaque changement devient une prise de risque opaque.
Modèle professionnel
CI/CD protégé
                            │
                            ├── change request
                            ├── plan archivé
                            ├── review
                            ├── approval
                            ├── apply manuel
                            ├── post-checks
                            └── documentation
Résultat : l’équipe peut modifier l’infrastructure avec discipline, traçabilité et capacité de réaction.
Checklist de déploiement infrastructure
Avant merge
PointValidation attendue
Ticket / change requestObjectif, impact, risque, rollback décrits.
Terraform fmtFormat OK.
Terraform validateValidation OK.
Scan sécuritéPas de risque bloquant non traité.
PlanPlan généré, lisible et archivé.
ReviewPlan relu par une personne compétente.
Destroy / replaceAbsents ou explicitement justifiés.
RollbackProcédure écrite ou mitigation claire.
Avant apply production
QuestionRéponse attendue
Est-ce la bonne branche ?main ou branche protégée prévue.
Est-ce le bon environnement ?Production clairement affichée.
Le state est-il verrouillé ?Backend distant + locking actif.
La fenêtre est-elle correcte ?Oui si changement à risque.
Les personnes clés sont-elles disponibles ?Oui pour changement élevé/critique.
Les dashboards sont-ils ouverts ?Oui avant apply.
Le rollback est-il réalisable ?Oui ou mitigation documentée.
Après apply
CloudRessources healthy.
AppHealthchecks OK.
LogsPas de nouvelles erreurs critiques.
MetricsLatence, erreurs, CPU/RAM stables.
AlertingAucune alerte inattendue.
DocumentationChangement clôturé avec résultat.
Définition d’un bon déploiement infra : changement compris, plan relu, apply contrôlé, production vérifiée et rollback possible.
Mini-cheat-sheet
# Avant MR
                    terraform fmt -check -recursive
                    terraform validate
                    terraform plan -var-file="prod.tfvars" -out="tfplan"
                    terraform show -no-color tfplan > plan.txt

                    # Apply contrôlé
                    terraform apply tfplan

                    # Vérification
                    terraform output
                    terraform state list
                    curl -fsS https://example.com/health/

                    # En cas de doute
                    terraform plan -refresh-only
3.1 Observabilité : logs, métriques, traces, alertes et dashboards
L’observabilité n’est pas seulement du monitoring

Le monitoring répond à la question : “est-ce que ça va ?”. L’observabilité répond à une question plus profonde : “pourquoi ça ne va pas, où, depuis quand, et avec quel impact ?”.

En production, l’observabilité permet de diagnostiquer rapidement les incidents, vérifier un déploiement, comprendre les performances, réduire le MTTR et piloter la fiabilité réelle du service.

Objectif professionnel : ne pas attendre qu’un utilisateur signale un problème. La plateforme doit détecter, alerter, expliquer et guider l’investigation.
Les questions à couvrir
QuestionSignal utile
Le service est-il disponible ?Health checks, uptime, taux de succès HTTP.
Le service est-il lent ?Latence p50, p95, p99, temps DB, temps externe.
Le service échoue-t-il ?5xx, exceptions, erreurs applicatives, failed jobs.
Quelle ressource sature ?CPU, RAM, disque, I/O, connexions DB, queue depth.
Quel changement a déclenché l’incident ?Déploiements, Terraform apply, feature flags, logs audit.
Quel utilisateur ou service est impacté ?Logs structurés, traces, labels, dimensions métier.
Diagramme d’observabilité production
Production system
                            │
                            ├── Application
                            ├── Reverse proxy / Load balancer
                            ├── Database
                            ├── Cache
                            ├── Workers / queues
                            ├── Cloud resources
                            └── CI/CD / Terraform
                            │
                            ▼
                            Telemetry
                            ├── logs
                            ├── metrics
                            ├── traces
                            ├── events
                            └── audit trail
                            │
                            ▼
                            Observability platform
                            ├── dashboards
                            ├── alerting
                            ├── search
                            ├── correlation
                            └── incident response
Observabilité utile vs bruit
Signal utileBruit inutile
Erreur 5xx avec route, service, trace ID.Log générique “error occurred”.
Latence p95 par endpoint critique.Moyenne globale masquant les pics.
Alerte sur impact utilisateur.Alerte CPU isolée sans contexte.
Dashboard orienté service.Dashboard rempli de graphes jamais lus.
Règle : une métrique ou une alerte doit aider à prendre une décision. Sinon, elle devient du bruit opérationnel.
Les piliers de l’observabilité
Logs

Ce que les systèmes déclarent : requêtes, erreurs, exceptions, événements métier, actions utilisateur, changements d’état.

Métriques

Ce que les systèmes mesurent : CPU, RAM, disque, latence, 5xx, throughput, saturation, temps de réponse.

Traces

Le parcours d’une requête à travers plusieurs services : API, DB, cache, service externe, worker.

Piliers complémentaires
PilierUsageExemple
EventsMarquer les changements importants.Déploiement, Terraform apply, scaling event.
Audit logsTracer les actions sensibles.Qui a modifié IAM, security group, secret.
SLO / SLIMesurer la fiabilité du point de vue utilisateur.99.9% de requêtes API réussies sous 300 ms.
DashboardsVoir rapidement l’état de production.Golden signals, infra, DB, CI/CD.
AlertingNotifier quand une action humaine est nécessaire.Erreur 5xx élevée pendant 5 minutes.
Corrélation des signaux
Incident API lent
                            │
                            ├── Metrics
                            │     └── p95 latency augmente
                            │
                            ├── Logs
                            │     └── slow queries visibles
                            │
                            ├── Traces
                            │     └── temps passé dans PostgreSQL
                            │
                            ├── Events
                            │     └── déploiement 10 min avant
                            │
                            └── Audit
                            └── changement paramètre DB
Point clé : aucun pilier ne suffit seul. Les incidents sérieux se comprennent par corrélation : métriques + logs + traces + événements.
Logs : rendre les événements exploitables

Les logs doivent aider à comprendre ce qui s’est passé. En production, des logs utiles sont structurés, filtrables, corrélables et suffisamment précis sans exposer de secrets.

Logs à collecter
SourceExemplesUtilité
ApplicationExceptions, erreurs métier, login, jobs.Comprendre le comportement applicatif.
Nginx / proxyAccess logs, status code, latence, IP.Analyser trafic et erreurs HTTP.
Systemsystemd, kernel, auth, disk.Diagnostiquer serveur Linux.
DatabaseSlow queries, locks, connexions, erreurs.Identifier saturation ou requêtes lentes.
CI/CDPipeline failed, Terraform apply, déploiements.Relier incident à changement récent.
Cloud auditIAM changes, SG changes, console actions.Détecter changements manuels ou suspects.
Bon log structuré
{
                            "level": "error",
                            "service": "api",
                            "environment": "prod",
                            "request_id": "req-8f31",
                            "trace_id": "tr-91ab",
                            "user_id": "u_12345",
                            "route": "/api/orders",
                            "status_code": 500,
                            "duration_ms": 842,
                            "error": "database_timeout"
                            }
Bonnes pratiques logs
PratiquePourquoi
Logs structurés JSONRecherches et agrégations beaucoup plus fiables.
Request ID / Trace IDCorréler logs entre services.
Niveau clairdebug, info, warning, error, critical.
Pas de secretsÉviter fuite token, mot de passe, cookie, Authorization header.
Rétention adaptéeCoût, conformité, capacité d’investigation.
Indexation utileService, environnement, route, status, trace ID.
Commandes utiles Linux
journalctl -u nginx -n 100 --no-pager
                            journalctl -u app.service -f
                            tail -f /var/log/nginx/access.log
                            tail -f /var/log/nginx/error.log
                            grep " 500 " /var/log/nginx/access.log
Règle : ne jamais logger les mots de passe, tokens, clés API, cookies de session ou headers Authorization.
Métriques : mesurer l’état réel du système

Les métriques permettent de détecter les tendances, saturations, régressions et incidents. Elles sont indispensables pour les dashboards, alertes, SLO et analyses post-incident.

Golden signals
SignalSignificationExemples
LatencyTemps de réponse ressenti.p50, p95, p99 par endpoint.
TrafficVolume de demandes.RPS, jobs/min, messages queue.
ErrorsTaux d’échec.5xx, exceptions, failed jobs.
SaturationRessources proches de la limite.CPU, RAM, disque, connexions DB.
Métriques système
CPUUsage, load average, steal time.
RAMUtilisation, swap, OOM kills.
DisqueUsage %, I/O wait, inode usage.
RéseauDébit, erreurs, connexions, drops.
Métriques applicatives et DB
DomaineMétriques clés
HTTPRPS, 2xx/4xx/5xx, latence p95, taille réponse.
ApplicationExceptions, temps traitement, cache hit ratio.
WorkersQueue length, job duration, failed jobs, retries.
PostgreSQL/MySQLConnexions, slow queries, locks, replication lag.
RedisMemory, evictions, hit ratio, connected clients.
CI/CDPipeline duration, failed jobs, deploy frequency.
Diagramme métriques → décision
Métrique collectée
                            │
                            ▼
                            Dashboard
                            │
                            ├── tendance normale
                            ├── pic temporaire
                            └── anomalie durable
                            │
                            ▼
                            Alerte si seuil + durée + impact
                            │
                            ▼
                            Investigation logs / traces
                            │
                            ▼
                            Action : scale, rollback, fix, mitigation
Bonne pratique : utiliser des percentiles comme p95/p99. Les moyennes cachent souvent les vrais problèmes utilisateurs.
Traces distribuées : comprendre le chemin d’une requête

Les traces montrent le parcours d’une requête entre services : frontend, API, base de données, cache, services externes, workers. Elles sont essentielles dans les architectures microservices ou les applications avec beaucoup de dépendances.

Exemple de trace
Request: POST /api/orders
                            │
                            ├── API Gateway               12 ms
                            ├── Auth service              28 ms
                            ├── Order API                120 ms
                            │     ├── PostgreSQL query    85 ms
                            │     ├── Redis cache          4 ms
                            │     └── Payment API        410 ms
                            └── Response total           590 ms
Ce qu’une trace révèle
SignalInterprétation
Span très longService ou requête DB lente.
Erreur sur span externeDépendance tierce en échec.
Beaucoup de spans DBPossible problème N+1 queries.
Trace sans request IDCorrélation logs difficile.
Outils de tracing
OutilUsage
OpenTelemetryStandard d’instrumentation traces/metrics/logs.
JaegerTracing distribué open source.
Grafana TempoStockage traces intégré écosystème Grafana.
Datadog APMAPM SaaS complet avec traces, metrics, logs.
New RelicAPM, monitoring et analyse applicative.
Traces + logs
trace_id = tr-91ab
                            │
                            ├── visible dans la trace APM
                            ├── présent dans les logs API
                            ├── présent dans les logs worker
                            └── utilisé pour rechercher l'incident complet
Conseil : le tracing devient très rentable dès qu’une requête traverse plusieurs services, ou quand la latence vient de dépendances externes.
Alertes : prévenir sans noyer l’équipe

Une bonne alerte doit indiquer une action humaine nécessaire. Trop d’alertes créent de la fatigue, et l’équipe finit par les ignorer.

Tableau d’alertes production
DomaineAlerte typiqueAction attendue
HTTP5xx > 2% pendant 5 min.Vérifier app, déploiement récent, logs.
Latencep95 > 1s pendant 10 min.Analyser DB, cache, dépendances.
DisqueDisk usage > 85%.Nettoyer, augmenter volume, vérifier logs.
DatabaseConnexions > 80% max.Analyser pooling, requêtes, saturation.
QueueBacklog augmente pendant 15 min.Vérifier workers, erreurs, scaling.
CI/CDPipeline prod failed.Vérifier état partiel, state lock, rollback.
Règle : une alerte sans runbook ni action claire est souvent une mauvaise alerte.
Niveaux d’alerte
NiveauImpactCanal
InfoÉvénement notable, pas d’action immédiate.Dashboard, log, notification faible.
WarningRisque ou tendance à surveiller.Slack/Email équipe.
CriticalImpact utilisateur ou risque immédiat.Pager/on-call + canal incident.
Diagramme anti-bruit
Signal brut
                            │
                            ▼
                            Seuil + durée
                            │
                            ▼
                            Impact utilisateur ?
                            │
                            ├── Non : dashboard / warning
                            └── Oui : alerte critique
                            │
                            ▼
                            Runbook associé
                            │
                            ▼
                            Action humaine claire
Exemple règle Prometheus
- alert: HighHttp5xxRate
                            expr: rate(http_requests_total{status=~"5.."}[5m]) 
                            / rate(http_requests_total[5m]) > 0.02
                            for: 5m
                            labels:
                            severity: critical
                            annotations:
                            summary: "High HTTP 5xx rate"
                            runbook: "https://runbooks.example.com/http-5xx"
Dashboards : voir vite ce qui compte

Un dashboard production doit répondre rapidement aux questions de santé, performance, capacité et impact. Il doit être lisible en incident.

Dashboard minimal production
DomaineIndicateursPourquoi
Vue serviceDisponibilité, RPS, 5xx, p95/p99.État utilisateur.
ApplicationExceptions, endpoints lents, jobs failed.Diagnostic métier.
InfrastructureCPU, RAM, disque, réseau.Saturation ressources.
DatabaseConnexions, locks, slow queries, replication lag.Cause fréquente de lenteur.
Cache / queueHit ratio, evictions, backlog, retries.Performance et async.
DéploiementsDernier deploy, Terraform apply, version.Corrélation incident/changement.
Organisation recommandée
Dashboard global
                            │
                            ├── Service health
                            ├── Errors / latency
                            ├── Traffic
                            └── Recent changes

                            Dashboards spécialisés
                            ├── API
                            ├── Database
                            ├── Workers
                            ├── Infrastructure
                            ├── CI/CD
                            └── Security / Audit
Bon design de dashboard
Bonne pratiqueRaison
Vue haut niveau en premierComprendre la santé générale en 30 secondes.
PercentilesMontrer les vrais problèmes de latence.
Labels env/serviceFiltrer prod/staging/dev et composants.
Annotations deployCorréler changement et incident.
Peu mais utileÉviter 80 graphes illisibles.
Runbook liéPasser du constat à l’action.
Exemple de panneaux
Production Overview
                            - Availability
                            - Requests per second
                            - HTTP 5xx rate
                            - Latency p95 / p99
                            - Top slow endpoints
                            - Database connections
                            - Queue backlog
                            - Last deployment
                            - Active critical alerts
Objectif : en incident, un bon dashboard doit réduire le temps de compréhension, pas impressionner par le nombre de graphes.
Observabilité en production : cas concrets
Cas 1 : hausse des erreurs 5xx après déploiement
Signal5xx passe de 0.1% à 4% après release.
DashboardErreur HTTP, endpoint impacté, version déployée.
LogsExceptions sur route /api/orders.
TraceErreur lors appel payment provider.
ActionRollback applicatif ou feature flag.
Cas 2 : saturation disque
SignalDisque > 90%, logs en croissance rapide.
Cause possibleLogs debug activés, rotation absente, batch bavard.
Action immédiateNettoyage contrôlé, rotation logs, extension volume.
PréventionAlerting 75/85/95%, logrotate, rétention.
Cas 3 : base de données lente
SignalLatence p95 augmente, CPU DB élevé, slow queries.
LogsRequêtes lentes, locks, timeout.
MétriquesConnexions saturées, I/O wait, cache hit ratio faible.
ActionIdentifier requête, index, pooling, rollback si régression.
Cas 4 : pipeline Terraform échoué
SignalJob apply prod failed.
RisqueChangement partiellement appliqué.
Vérificationterraform plan, state lock, ressources cloud modifiées.
ActionNe pas relancer aveuglément, analyser état partiel.
Bon réflexe : après un changement infra ou applicatif, regarder les dashboards immédiatement, puis encore quelques minutes plus tard.
Outils d’observabilité
Stack open source fréquente
OutilRôle
PrometheusCollecte et stockage de métriques.
GrafanaDashboards et visualisation.
AlertmanagerRoutage et gestion des alertes.
LokiLogs orientés labels, intégré Grafana.
ELK / OpenSearchRecherche et analyse de logs.
Jaeger / TempoTracing distribué.
OpenTelemetryStandard d’instrumentation et collecte.
Stack SaaS fréquente
DatadogMétriques, logs, traces, APM, SLO.
New RelicAPM, infrastructure, logs, monitoring.
DynatraceAPM entreprise, auto-discovery, IA ops.
CloudWatchMonitoring natif AWS.
Azure MonitorMonitoring natif Azure.
Google Cloud MonitoringMonitoring natif GCP.
Architecture type
Applications / Infra
                            │
                            ├── exporters
                            ├── agents
                            ├── SDK OpenTelemetry
                            └── log shippers
                            │
                            ▼
                            Collecte
                            ├── Prometheus
                            ├── Fluent Bit / Vector
                            ├── OpenTelemetry Collector
                            └── Cloud agents
                            │
                            ▼
                            Stockage / plateforme
                            ├── Grafana stack
                            ├── ELK / OpenSearch
                            ├── Datadog
                            └── Cloud native monitoring
                            │
                            ▼
                            Dashboards + Alerts + Incident response
Choix rapide
BesoinOption adaptée
Petit projet cloud AWSCloudWatch + dashboards simples.
Stack open sourcePrometheus + Grafana + Loki.
Logs puissantsELK / OpenSearch.
MicroservicesOpenTelemetry + tracing.
Entreprise multi-stackDatadog / New Relic / Dynatrace.
Conseil : choisir une stack que l’équipe sait exploiter. Un outil puissant mais incompris ne réduit pas le MTTR.
Anti-patterns observabilité
Anti-patternPourquoi c’est dangereuxAlternative professionnelle
Pas d’alertes avant prodLes utilisateurs détectent les incidents avant l’équipe.Alertes minimales avant mise en ligne.
Trop d’alertesFatigue, alertes ignorées.Alertes orientées impact et action.
Logs non structurésRecherche lente et corrélation difficile.JSON logs avec request_id/trace_id.
Pas de corrélation deployImpossible de relier incident à changement récent.Annotations de déploiement et events.
Dashboard trop denseIllisible en incident.Vue synthétique + dashboards spécialisés.
Seuils arbitrairesFaux positifs ou faux négatifs.Seuils basés sur baseline et SLO.
Logger des secretsFuite de tokens ou données sensibles.Redaction, filtres, interdiction headers sensibles.
Pas de runbookL’alerte ne guide pas l’action.Chaque alerte critique a un runbook.
Mauvais modèle
Production
                            │
                            ├── logs dispersés
                            ├── pas de métriques p95
                            ├── alertes CPU bruyantes
                            ├── pas de traces
                            ├── pas de dashboard incident
                            └── pas de runbook
Résultat : chaque incident devient une enquête longue et confuse.
Modèle professionnel
Production observable
                            │
                            ├── logs structurés
                            ├── métriques golden signals
                            ├── traces corrélées
                            ├── dashboards lisibles
                            ├── alertes actionnables
                            ├── events de déploiement
                            └── runbooks associés
Résultat : détection rapide, diagnostic clair, MTTR réduit.
Checklist observabilité production
Checklist minimale avant go-live
PointValidation attendue
Health checkEndpoint fiable pour vérifier le service.
Logs centralisésApplication, proxy, workers, erreurs.
Métriques HTTPRPS, 5xx, latence p95/p99.
Métriques systèmeCPU, RAM, disque, réseau.
Métriques DBConnexions, slow queries, locks, stockage.
Alertes critiquesService down, 5xx, disque, DB saturation.
Dashboard globalVue production lisible rapidement.
RunbooksActions associées aux alertes principales.
Checklist après déploiement
QuestionRéponse attendue
Les health checks sont-ils OK ?Oui, stable.
Les 5xx augmentent-ils ?Non ou attendu.
La latence p95/p99 change-t-elle ?Stable ou amélioration.
Les logs montrent-ils de nouvelles exceptions ?Non.
La DB est-elle stable ?Connexions, locks, slow queries OK.
Les workers suivent-ils ?Pas de backlog anormal.
Des alertes nouvelles sont-elles apparues ?Non critique.
Le changement est-il annoté ?Oui, deploy/Terraform event visible.
Définition d’une production observable : l’équipe peut détecter un problème, comprendre son périmètre, identifier sa cause probable et agir sans improviser.
Mini-cheat-sheet
# Logs
                            journalctl -u app.service -f
                            tail -f /var/log/nginx/error.log

                            # HTTP
                            curl -fsS https://example.com/health/

                            # Métriques clés
                            HTTP 5xx rate
                            Latency p95 / p99
                            CPU / RAM / Disk
                            DB connections / slow queries
                            Queue backlog
                            Pipeline failures

                            # Alertes minimales
                            Service down
                            5xx high
                            Disk > 85%
                            DB connections high
                            Queue backlog high
                            Prod pipeline failed
3.2 Incidents production : qualifier, mitiger, restaurer et prévenir
Un incident production est un événement opérationnel, pas seulement un bug

Un incident production est une situation où un service réel est dégradé, indisponible, lent, instable, incorrect, non sécurisé ou incapable de remplir sa fonction métier. Il peut venir du code applicatif, de l’infrastructure, du réseau, de la base de données, d’un déploiement, d’un fournisseur externe, d’un problème sécurité ou d’une erreur humaine.

La priorité pendant l’incident n’est pas de trouver un coupable ni de rédiger une analyse parfaite. La priorité est de restaurer le service, réduire l’impact utilisateur, communiquer clairement, puis analyser à froid pour éviter la récidive.

Principe fondamental : pendant l’incident, on restaure d’abord. Après stabilisation, on analyse profondément.
Les objectifs d’une gestion d’incident professionnelle
ObjectifRésultat attendu
QualifierComprendre rapidement l’impact, la gravité et le périmètre.
StabiliserÉviter que l’incident empire ou se propage.
MitigerRestaurer partiellement ou totalement le service.
CommuniquerInformer clairement les parties prenantes sans spéculation.
RestaurerValider le retour au nominal par des signaux mesurables.
AnalyserIdentifier cause racine, facteurs contributifs et actions préventives.
Cycle incident complet
Détection
                            │
                            ▼
                            Qualification
                            ├── impact utilisateur
                            ├── service touché
                            ├── gravité
                            └── périmètre
                            │
                            ▼
                            Stabilisation
                            ├── stopper changement
                            ├── éviter propagation
                            └── geler actions risquées
                            │
                            ▼
                            Mitigation
                            ├── rollback
                            ├── scale
                            ├── bypass
                            ├── feature flag off
                            └── correctif minimal
                            │
                            ▼
                            Vérification
                            ├── métriques
                            ├── logs
                            ├── health checks
                            └── parcours métier
                            │
                            ▼
                            Post-mortem
                            ├── chronologie
                            ├── cause racine
                            ├── facteurs contributifs
                            └── actions préventives
Signaux typiques d’incident
SignalInterprétation possible
HTTP 5xx élevéErreur applicative, DB, dépendance externe, config.
Latence p95/p99 élevéeDB lente, saturation CPU, queue, API externe lente.
Healthcheck KOService indisponible ou dépendance critique KO.
Queue backlogWorkers bloqués, volume trop élevé, erreur répétée.
State lock TerraformPipeline actif, lock orphelin ou apply bloqué.
Disque pleinLogs excessifs, backup bloqué, rotation absente.
Bon réflexe DevOps : toujours relier l’incident à un changement récent : déploiement, apply Terraform, changement config, scaling, DNS, IAM, DB ou secret.
Classification de gravité : SEV / impact / priorité

La classification évite les discussions floues. Elle permet de décider qui mobiliser, quelle communication envoyer, à quelle fréquence donner des updates et quel niveau d’urgence appliquer.

Table de sévérité
NiveauImpactExemplesRéponse
SEV-1Service critique indisponible ou perte de données.Site down, API principale KO, DB prod inaccessible.Mobilisation immédiate, canal incident, updates fréquents.
SEV-2Dégradation forte mais contournement possible.Latence élevée, fonctionnalité clé dégradée.Réponse rapide, responsable incident nommé.
SEV-3Impact partiel ou non critique.Batch retardé, dashboard interne KO.Traitement prioritaire mais sans mobilisation totale.
SEV-4Faible impact ou anomalie préventive.Alerte capacité, warning sécurité, bug mineur.Suivi normal, planification correction.
Attention : il vaut mieux surclasser temporairement un incident puis le réduire que sous-estimer un incident réel pendant 30 minutes.
Critères de qualification
CritèreQuestion
UtilisateursCombien d’utilisateurs sont touchés ? Tous, certains, un segment ?
Fonction métierLogin, paiement, API, backoffice, batch, reporting ?
DuréeDepuis quand le problème existe-t-il ?
DégradationDown total, lent, intermittent, erreurs partielles ?
DonnéesRisque de perte, corruption ou exposition ?
SécuritéY a-t-il fuite, accès non autorisé ou vulnérabilité active ?
Décision rapide
Incident détecté
                            │
                            ▼
                            Impact utilisateur réel ?
                            │
                            ├── Non : SEV-3 / SEV-4 possible
                            └── Oui
                            │
                            ▼
                            Service critique touché ?
                            │
                            ├── Oui : SEV-1 ou SEV-2
                            └── Non : SEV-2 ou SEV-3
                            │
                            ▼
                            Données ou sécurité impliquées ?
                            │
                            ├── Oui : escalade immédiate
                            └── Non : mitigation standard
Rôles pendant un incident

Un incident sérieux nécessite de la coordination. Sans rôles clairs, plusieurs personnes investiguent la même chose, personne ne communique, ou des actions contradictoires sont lancées.

Rôles recommandés
RôleResponsabilitéErreur à éviter
Incident CommanderCoordonne, décide, priorise, garde la vision globale.Tout faire soi-même.
Tech Lead IncidentPilote l’analyse technique et les hypothèses.Changer de piste toutes les 2 minutes.
Ops / DevOpsVérifie infra, logs, métriques, rollback, scaling.Appliquer des corrections sans validation.
App EngineerAnalyse code, erreurs applicatives, release récente.Ignorer les signaux infra.
Communications LeadInforme équipes, métier, clients si nécessaire.Communiquer des hypothèses comme des faits.
ScribeNote chronologie, décisions, commandes, heures.Reconstituer après coup de mémoire.
Organisation du canal incident
#incident-sev1-api
                            │
                            ├── Incident Commander
                            ├── DevOps
                            ├── Backend engineer
                            ├── Database expert
                            ├── Communications lead
                            └── Scribe
                            │
                            ▼
                            Messages courts :
                            ├── observation
                            ├── hypothèse
                            ├── action proposée
                            ├── décision
                            └── résultat
Règles de canal
Un responsable incident clairÉvite les décisions contradictoires.
Pas de débat long en criseOn privilégie actions réversibles et vérifiables.
Chaque action annoncéeCommande, rollback, restart, scaling, changement config.
Chaque action vérifiéeOn mesure le résultat, pas d’impression vague.
Chronologie tenueIndispensable pour RCA et post-mortem.
Bonne pratique : en SEV-1, séparer coordination, investigation et communication. Une seule personne ne peut pas tout faire correctement.
Méthode en 6 étapes
  1. Qualifier : identifier qui est impacté, quel service est touché, depuis quand, avec quelle gravité.
  2. Stabiliser : stopper les déploiements, éviter les changements concurrents, empêcher l’incident de s’étendre.
  3. Mitiger : rollback, restart contrôlé, scale, bypass, désactivation feature flag, correction minimale.
  4. Communiquer : envoyer des messages courts, factuels, réguliers, sans spéculation excessive.
  5. Restaurer : vérifier retour au nominal par métriques, logs, health checks, parcours métier.
  6. Analyser : cause racine, facteurs contributifs, actions préventives, suivi post-mortem.
Pendant l’incident : l’objectif n’est pas de prouver qui a tort, mais de restaurer le service et réduire l’impact.
Actions rapides possibles
ActionQuand l’utiliserRisque
Rollback appIncident après release applicative.Perte de correction récente.
Rollback TerraformIncident après changement infra.Plan de rollback à relire.
Feature flag offFonctionnalité nouvelle problématique.Fonction désactivée temporairement.
Scale upSaturation capacité.Coût, masque cause racine.
Bypass dépendanceAPI externe ou service secondaire KO.Mode dégradé.
Flux opérationnel
Détection
                            │
                            ▼
                            Triage rapide
                            ├── impact
                            ├── gravité
                            ├── service
                            └── changement récent
                            │
                            ▼
                            Hypothèse principale
                            │
                            ├── app release ?
                            ├── Terraform apply ?
                            ├── DB saturation ?
                            ├── provider externe ?
                            └── réseau / IAM ?
                            │
                            ▼
                            Action réversible
                            │
                            ▼
                            Mesure du résultat
                            │
                            ├── amélioration : continuer stabilisation
                            └── pas d'effet : nouvelle hypothèse
                            │
                            ▼
                            Retour nominal
                            │
                            ▼
                            RCA et prévention
Commandes utiles en première analyse
# HTTP
                            curl -fsS https://example.com/health/

                            # Linux services
                            systemctl status app.service
                            journalctl -u app.service -n 100 --no-pager

                            # Nginx
                            tail -n 100 /var/log/nginx/error.log
                            grep " 500 " /var/log/nginx/access.log | tail

                            # Terraform
                            terraform plan -refresh-only
                            terraform state list

                            # Disk / system
                            df -h
                            free -m
                            top
Attention : éviter les commandes destructives en crise. Toute action doit être annoncée, comprise et vérifiée.
Chronologie d’incident : l’outil indispensable

Une bonne chronologie permet de comprendre la séquence réelle : détection, hypothèses, actions, résultats, retour nominal. Elle évite les reconstructions approximatives après coup.

Exemple de chronologie SEV-1
TempsAction / observationBut
T+0Alerte 5xx élevée sur API production.Détection.
T+3Dashboard confirme 5xx sur /api/orders.Confirmer impact.
T+5Canal incident créé, Incident Commander nommé.Coordination.
T+8Dernier déploiement app identifié à T-10.Hypothèse principale.
T+12Rollback release applicative lancé.Mitigation.
T+185xx descend progressivement.Vérifier efficacité.
T+25Health checks et parcours métier OK.Retour nominal.
T+45Surveillance prolongée, aucun nouveau pic.Stabilisation.
T+90Post-mortem démarré.Prévention.
Format de note chronologique
[21:04] Alerte HighHttp5xxRate déclenchée.
                            [21:06] Dashboard API confirme 5xx à 4.8%.
                            [21:08] Incident SEV-1 déclaré. IC: Alice.
                            [21:10] Dernier deploy API identifié : commit abc123.
                            [21:12] Décision : rollback API vers version précédente.
                            [21:16] Rollback terminé.
                            [21:20] 5xx revenus sous 0.2%.
                            [21:25] Health checks OK.
                            [21:35] Communication : service stabilisé.
                            [22:00] Début RCA.
À noter systématiquement
Heure de détectionQuand l’incident a été vu.
Heure de début réelQuand les métriques montrent le début.
Actions prisesRollback, restart, scale, hotfix, changement config.
DécisionsPourquoi une piste a été choisie.
RésultatsEffet mesuré après action.
Retour nominalQuand les signaux sont redevenus stables.
Bonne pratique : écrire la timeline pendant l’incident, pas deux jours plus tard.
Mitigation : restaurer vite sans aggraver

La mitigation vise à réduire l’impact avant même d’avoir une compréhension complète. Elle doit être rapide, proportionnée, réversible et mesurable.

Catalogue de mitigations
IncidentMitigation rapideVérification
Release applicative casséeRollback image/version précédente.5xx, healthcheck, parcours critique.
Security group trop restrictifRestaurer règle précédente ou correctif minimal.Connectivité service → DB.
Saturation CPUScale up/out temporaire.CPU, latence, erreurs.
DB connexions saturéesRéduire workers, ajuster pool, redémarrage contrôlé.Connexions, locks, erreurs DB.
API externe lenteTimeout, circuit breaker, mode dégradé.Latence et erreurs endpoint.
Disque pleinNettoyage logs/cache, extension volume.df -h, logs, service OK.
DNS incorrectRestaurer record précédent.dig, curl, trafic réel.
Diagramme de décision mitigation
Incident actif
                            │
                            ▼
                            Cause probable liée à un changement récent ?
                            │
                            ├── Oui
                            │     ├── rollback app
                            │     ├── revert Terraform
                            │     └── désactiver feature flag
                            │
                            └── Non
                            ├── scale temporaire
                            ├── bypass dépendance
                            ├── redémarrage contrôlé
                            ├── restauration connectivité
                            └── mode dégradé
                            │
                            ▼
                            Mesurer impact
                            │
                            ├── amélioration : stabiliser
                            └── pas d'amélioration : nouvelle hypothèse
Actions à éviter en urgence
Faire plusieurs changements simultanésImpossible de savoir ce qui a aidé ou empiré.
Modifier la DB sans backupRisque de corruption ou perte.
Force-unlock Terraform sans preuvePeut casser un apply actif.
Ouvrir largement le réseauCrée une dette sécurité immédiate.
Redémarrer tous les services au hasardPeut aggraver la panne ou perdre indices.
Règle : une mitigation doit être annoncée, exécutée une par une, puis mesurée avant d’enchaîner.
Communication incident : courte, factuelle, régulière

Une communication claire réduit la panique, évite les interruptions inutiles et donne confiance dans la gestion de crise. Elle doit distinguer faits confirmés, hypothèses et prochaines actions.

Règles de communication
RèglePourquoi
Être factuelÉviter spéculation et contradictions.
Dire ce qui est impactéService, fonctionnalité, région, clients.
Dire ce qui est faitMitigation, rollback, investigation.
Donner un prochain updateRéduit les sollicitations.
Ne pas désigner de coupableGarder une culture blameless.
Ne pas promettre sans certitudePréserver crédibilité.
Message initial interne
Incident SEV-2 en cours sur API production.
                            Impact confirmé : hausse des erreurs 5xx sur /api/orders.
                            Début estimé : 14:06.
                            Action en cours : analyse dernier déploiement et logs applicatifs.
                            Prochain update : dans 10 minutes.
Messages de suivi
Update 14:20 :
                            Cause probable identifiée : release API 2026.04.29-3.
                            Action : rollback vers version précédente en cours.
                            Les erreurs 5xx restent élevées mais stables.
                            Prochain update : 14:30.

                            Update 14:32 :
                            Rollback terminé.
                            Les 5xx sont revenus sous le seuil normal.
                            Surveillance prolongée pendant 30 minutes.
                            Post-mortem suivra.
Communication externe éventuelle
Nous observons actuellement une dégradation sur une partie des appels API.
                            Notre équipe a identifié le problème et applique une mesure de mitigation.
                            Nous publierons une mise à jour dès que le service sera pleinement stabilisé.
Attention : en communication client, éviter les détails internes inutiles : noms de personnes, secrets, architecture sensible, hypothèses non confirmées.
RCA : Root Cause Analysis

La RCA vise à comprendre pourquoi l’incident est arrivé et pourquoi les protections existantes ne l’ont pas empêché ou détecté plus tôt. Elle ne doit pas s’arrêter au symptôme immédiat.

Symptôme vs cause racine
NiveauExemple
SymptômeAPI retourne 500.
Cause technique immédiateTimeout PostgreSQL sur endpoint commandes.
Cause technique profondeNouvelle requête sans index déclenche full scan.
Cause processPas de test de volume ni alerte slow query en staging.
PréventionAjouter index, test perf, alerte slow query, review SQL.
Méthode des 5 pourquoi
Pourquoi l'API était lente ?
                            -> PostgreSQL répondait lentement.

                            Pourquoi PostgreSQL répondait lentement ?
                            -> Une requête faisait un scan complet.

                            Pourquoi la requête faisait un scan complet ?
                            -> Un index manquait sur une colonne filtrée.

                            Pourquoi l'index manquait ?
                            -> La migration n'a pas été revue côté performance.

                            Pourquoi ce risque n'a pas été détecté ?
                            -> Pas de test sur volume représentatif en staging.
Facteurs contributifs
FamilleQuestions
TechniqueCode, infra, DB, réseau, provider, capacité ?
ProcessReview, tests, approvals, runbooks suffisants ?
ObservabilitéAlerte trop tardive ? Dashboard insuffisant ?
OrganisationOwnership clair ? Escalade rapide ?
DocumentationRollback connu ? Procédure à jour ?
Diagramme RCA
Incident
                            │
                            ▼
                            Impact utilisateur
                            │
                            ▼
                            Symptôme visible
                            │
                            ▼
                            Cause technique immédiate
                            │
                            ▼
                            Cause technique profonde
                            │
                            ▼
                            Facteurs contributifs
                            ├── tests absents
                            ├── alerte absente
                            ├── review insuffisante
                            └── runbook manquant
                            │
                            ▼
                            Actions préventives vérifiables
Bonne RCA : elle produit des actions concrètes, assignées, datées et vérifiables. Pas seulement une explication.
Post-mortem blameless

Le post-mortem documente l’incident, son impact, la chronologie, les causes, ce qui a bien fonctionné, ce qui doit être amélioré et les actions de prévention. Il doit être sans blâme, mais pas sans exigence.

Template post-mortem
# Incident : titre court

                            ## Résumé
                            - Date :
                            - Durée :
                            - Gravité :
                            - Services concernés :
                            - Statut final :

                            ## Impact
                            - Utilisateurs touchés :
                            - Fonctionnalités touchées :
                            - Impact métier :
                            - Données impactées :
                            - Impact sécurité :

                            ## Chronologie
                            - HH:MM Détection
                            - HH:MM Qualification
                            - HH:MM Première mitigation
                            - HH:MM Retour partiel
                            - HH:MM Retour nominal
                            - HH:MM Fin surveillance

                            ## Cause racine
                            - Cause technique :
                            - Cause process :
                            - Facteurs contributifs :

                            ## Ce qui a bien fonctionné
                            - ...

                            ## Ce qui doit être amélioré
                            - ...

                            ## Actions préventives
                            - [ ] Action 1 - Owner - Date
                            - [ ] Action 2 - Owner - Date
                            - [ ] Action 3 - Owner - Date
Qualité des actions post-mortem
Mauvaise actionBonne action
Faire plus attention.Ajouter policy CI bloquant security group 0.0.0.0/0 sur DB.
Mieux tester.Ajouter test smoke /health/ post-deploy en pipeline prod.
Améliorer monitoring.Créer alerte p95 API > 1s pendant 10 min avec runbook.
Documenter.Créer runbook “rollback Terraform security group” avec commandes exactes.
Actions préventives typiques
  • Ajouter une alerte plus précoce.
  • Ajouter un test de pipeline ou smoke test.
  • Renforcer la review Terraform sur réseau/IAM/DB.
  • Ajouter un garde-fou policy-as-code.
  • Documenter le rollback.
  • Réduire le blast radius.
  • Ajouter dashboard spécifique.
  • Automatiser une vérification manuelle répétitive.
Attention : un post-mortem sans owner ni échéance produit rarement une amélioration réelle.
Exemples d’incidents production
Tableau de cas fréquents
IncidentMitigation rapidePrévention
Apply Terraform modifie un security group DB.Rollback règle réseau ou apply correctif minimal.Policy check + review renforcée des plans réseau.
Pipeline prod bloqué par state lock.Identifier job détenteur, attendre ou unlock après preuve.Timeout jobs, monitoring locks, runbook force-unlock.
Déploiement app casse healthcheck.Rollback image/release précédente.Canary + smoke tests CI + healthcheck réaliste.
Disque saturé.Nettoyage logs/cache, extension volume.Alerte disque + logrotate + rétention logs.
DB lente après release.Rollback release, désactivation feature, ajout index si validé.Slow query alert + tests volume + review SQL.
DNS pointe vers mauvaise cible.Restaurer record précédent.Review DNS + TTL adapté + vérification dig.
Cas détaillé : security group trop restrictif
Changement Terraform
                            │
                            ▼
                            Security group DB modifié
                            │
                            ▼
                            API ne peut plus joindre PostgreSQL
                            │
                            ▼
                            Symptômes
                            ├── 500 API
                            ├── logs database connection refused
                            ├── healthcheck KO
                            └── hausse latence
                            │
                            ▼
                            Mitigation
                            ├── restaurer règle SG précédente
                            ├── apply correctif minimal
                            └── vérifier connexion API → DB
                            │
                            ▼
                            Prévention
                            ├── review plan réseau
                            ├── test connectivité post-apply
                            ├── policy anti-ouverture/fermeture critique
                            └── runbook rollback SG
Cas détaillé : disque saturé
Symptômes :
                            - Erreurs écriture logs
                            - Service instable
                            - DB ou app ne peut plus créer fichiers temporaires

                            Commandes :
                            df -h
                            du -sh /var/log/*
                            journalctl --disk-usage

                            Mitigation :
                            - Nettoyage contrôlé
                            - Rotation logs
                            - Extension volume
                            - Restart uniquement si nécessaire

                            Prévention :
                            - Alerte disque 75/85/95%
                            - logrotate
                            - quotas/rétention
                            - dashboard stockage
Checklist gestion d’incident production
Checklist pendant incident
PointValidation
Incident déclaréCanal créé, gravité définie.
Responsable nomméIncident Commander identifié.
Impact qualifiéService, utilisateurs, durée, gravité.
Changement récent vérifiéDeploy app, Terraform apply, config, DB, provider.
Mitigation choisieAction réversible ou contrôlée.
Communication envoyéeMessage court, factuel, prochain update.
Chronologie tenueActions et heures notées.
Retour nominal vérifiéLogs, métriques, healthcheck, parcours métier.
Checklist technique rapide
[ ] Healthcheck KO ou OK ?
                            [ ] 5xx / 4xx anormaux ?
                            [ ] Latence p95 / p99 ?
                            [ ] Dernier déploiement ?
                            [ ] Dernier Terraform apply ?
                            [ ] DB connexions / locks / slow queries ?
                            [ ] Disque / CPU / RAM ?
                            [ ] Queue backlog ?
                            [ ] Provider externe ?
                            [ ] DNS / certificat / load balancer ?
                            [ ] Security group / IAM ?
Checklist après incident
PointRésultat attendu
Post-mortem crééDocument clair, partagé.
Timeline complèteDétection, mitigation, retour nominal.
Impact mesuréDurée, utilisateurs, services, données.
Cause racine identifiéeTechnique + process + observabilité.
Actions assignéesOwner + date + résultat vérifiable.
Runbook mis à jourProcédure améliorée.
Alerte ajustéeDétection plus rapide ou moins de bruit.
Prévention suivieActions fermées, pas oubliées.
Définition d’une bonne gestion d’incident : service restauré vite, communication claire, cause comprise, actions préventives réalisées.
Mini-cheat-sheet incident
1. Déclarer incident + gravité.
                            2. Nommer Incident Commander.
                            3. Qualifier impact.
                            4. Chercher changement récent.
                            5. Mitiger avec action réversible.
                            6. Mesurer effet.
                            7. Communiquer régulièrement.
                            8. Confirmer retour nominal.
                            9. Écrire post-mortem.
                            10. Fermer actions préventives.