⚙️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.
Vue d'ensemble DevOps
Le rôle DevOps côté infra : automatiser, fiabiliser, tracer et sécuriser.
CultureInfraProdTerraform : bases solides
Providers, resources, variables, outputs, plan/apply et cycle de vie.
IaCPlanApplyModules Terraform
Découper proprement réseau, compute, sécurité, base de données et applicatif.
ReusableVPCComputeState Terraform
Backend distant, locking, dérive, isolation par environnement et sécurité.
StateLockDriftGitLab CI/CD Infra
Stages fmt, validate, plan, review, apply et rollback contrôlé.
GitLabPipelineRunnerEnvironnements
Dev, staging, prod : variables protégées, branches, approvals et séparation.
DevStagingProdSecrets & sécurité CI
Variables masquées, scopes, credentials courts, policy least privilege.
SecretsOIDCIAMDéploiement infra
Workflow propre : changement, revue, plan, fenêtre de prod, apply et vérification.
ChangeReviewVerifyObservabilité
Logs, métriques, alertes, traces et tableaux de bord pour piloter la production.
LogsMetricsAlertsIncidents production
Qualifier, mitiger, restaurer, communiquer, analyser et éviter la récidive.
IncidentRCAPost‑mortemWhat 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.
Core responsibilities
| Area | What DevOps handles |
|---|---|
| Provisioning | Create VPCs, subnets, compute, IAM, load balancers, databases, DNS, storage. |
| Automation | Turn infrastructure changes into reviewed code and pipelines. |
| Reliability | Keep services available and reduce operational risk. |
| Security | Apply least privilege, secrets hygiene, network controls, auditability. |
| Observability | Provide logs, metrics, traces, dashboards, alerts, and health checks. |
| Incident response | Restore service fast, communicate clearly, then drive root cause analysis. |
The 6 professional pillars
| Pillar | Professional expectation |
|---|---|
| Infrastructure as Code | No critical production resource should exist only in a cloud console. |
| Delivery discipline | Every change goes through branch, merge request, plan, review, approval, apply. |
| State management | Terraform state is remote, protected, versioned, and locked. |
| Security baseline | Least privilege, secrets not stored in Git, protected runners, approvals. |
| Observability | Dashboards and alerts exist before the incident, not after. |
| Runbooks | Common 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 readinessWhat 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
└── alertingProduction constraints
| Constraint | Impact |
|---|---|
| Availability | Changes must avoid downtime or keep it minimal and controlled. |
| Security | Credentials, IAM roles, network exposure, and runner hardening matter. |
| Cost | DevOps must balance reliability with cloud spending. |
| Compliance | Audit trails, separation of duties, and approval flows may be mandatory. |
| Recovery | Backups 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.
Professional toolchain by responsibility
| Responsibility | Main tools | Typical usage |
|---|---|---|
| IaC | Terraform, Terragrunt, OpenTofu | Provision cloud resources, shared modules, environment structure. |
| CI/CD | GitLab CI/CD, GitHub Actions, Jenkins | Validate, plan, approve, apply, deploy, rollback. |
| Containers | Docker, Kubernetes, Helm | Package workloads, orchestrate services, manage releases. |
| Config management | Ansible, Salt, Chef | OS packages, user setup, service configuration. |
| Monitoring | Prometheus, Grafana, Datadog, CloudWatch | Metrics, dashboards, alerting, SLO tracking. |
| Logging | ELK, OpenSearch, Loki | Search logs, correlate incidents, root cause analysis. |
| Tracing | Jaeger, Tempo, Datadog APM | Latency analysis across services. |
| Secrets | Vault, AWS Secrets Manager, SSM Parameter Store | Store secrets outside Git and outside pipeline logs. |
| Security | Trivy, Checkov, tfsec, Snyk | Scan images, Terraform, dependencies, misconfigurations. |
Tool selection guidance
| If you need... | Prefer... |
|---|---|
| Managed cloud provisioning | Terraform modules + remote state + CI pipeline |
| Server configuration after provisioning | Ansible |
| Kubernetes release management | Helm + GitOps or CI/CD |
| Fast incident log search | ELK / OpenSearch / Loki |
| Secure secret lifecycle | Vault 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.
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 quality | Professional expectation |
|---|---|
| Reusable | Inputs and outputs are clear and minimal. |
| Safe | Default values do not expose public access unintentionally. |
| Readable | Variables, tags, and naming conventions are consistent. |
| Composable | Modules 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 topic | Best practice |
|---|---|
| Location | Use remote storage, not a local laptop file. |
| Locking | Prevent concurrent apply operations. |
| Access | Restrict who can read or modify the state. |
| Sensitivity | Assume 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| Stage | Goal |
|---|---|
| lint | Format and style consistency. |
| validate | Catch syntax and structural errors early. |
| security_scan | Detect risky Terraform patterns and policy violations. |
| plan | Show intended infrastructure changes before apply. |
| approval | Human control point for sensitive environments. |
| apply | Execute only in controlled, protected contexts. |
| post_deploy_checks | Verify service health, alarms, and smoke tests. |
Critical CI/CD controls
| Control | Why it matters |
|---|---|
| Protected branches | Prevent direct, unreviewed production changes. |
| Protected variables | Keep secrets out of untrusted branches. |
| Scoped runners | Reduce blast radius and credential exposure. |
| Manual apply in production | Provide an explicit checkpoint. |
| Artifacts | Preserve 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.
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
└── preventionExample incident in production
Security group update breaks database connectivity
- Alert shows API error rate spike and DB connection failures.
- On-call verifies a recent infrastructure change.
- Terraform plan/apply history identifies a modified security group rule.
- Immediate mitigation: revert or restore DB access rule.
- Confirm service health via application metrics and database checks.
- Write postmortem: why review missed it, what test/guardrail is needed.
Incident response roles
| Role | Responsibility |
|---|---|
| Incident lead | Coordinates technical response and decisions. |
| Communications lead | Updates stakeholders and customer-facing channels. |
| Operations engineer | Executes rollback, checks infra, validates mitigation. |
| Application engineer | Correlates 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.
How DevOps expectations differ by company type
| Company type | Typical DevOps focus | Examples of concern |
|---|---|---|
| Startup SaaS | Speed, automation, cost awareness, fast recovery. | Simple platform, small team, high pressure to deliver. |
| E-commerce | Traffic peaks, latency, checkout reliability, on-call maturity. | Black Friday readiness, scaling, payment path resilience. |
| Fintech / banking | Security, compliance, approval workflows, audit trail. | Separation of duties, secrets management, restricted access. |
| Industrial / enterprise IT | Stability, change control, hybrid systems, documentation. | Legacy integration, strict release windows. |
| Media / streaming | Scalability, 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.
Operational KPI, SLA, SLO, and reliability signals
| Metric | What it tells you |
|---|---|
| Availability | Percentage of time the service is reachable and working. |
| Error rate | How many requests fail over time. |
| Latency p95 / p99 | User-perceived speed under load. |
| MTTD | Mean time to detect an issue. |
| MTTR | Mean time to recover service. |
| Deployment frequency | How often the team ships safely. |
| Change failure rate | How often releases or changes introduce incidents. |
SLA / SLO / Error budget
| Concept | Meaning |
|---|---|
| SLA | External commitment to customers, often contractual. |
| SLO | Internal target for reliability or performance. |
| SLI | Measured indicator used to evaluate the SLO. |
| Error budget | Allowed 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-pattern | Why it is dangerous | Professional alternative |
|---|---|---|
| ClickOps only | Manual changes create drift and no audit trail. | Put infra in Terraform and review all changes. |
| Local state on laptops | Lost state and conflicting applies become likely. | Use protected remote state with locking. |
| Production apply from any branch | High blast radius and poor control. | Use protected branches, approvals, and environment gates. |
| No monitoring before go-live | Issues are discovered too late. | Create dashboards and alerts before release. |
| No rollback plan | Recovery becomes slow and chaotic. | Define mitigation and rollback before deployment. |
| Too much access in CI runners | Secrets and production scope are exposed. | Use least privilege and scope per environment. |
| Huge changesets | Hard to review and harder to recover from. | Prefer small, frequent, well-documented changes. |
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.
Exemples d’objets gérés
| Famille | Exemples concrets |
|---|---|
| Réseau | VPC, subnets, route tables, NAT gateway, firewall rules. |
| Compute | VM, autoscaling group, ECS service, Kubernetes node pool. |
| Sécurité | IAM roles, policies, security groups, KMS keys. |
| Données | RDS PostgreSQL, MySQL, Redis, buckets S3, volumes. |
| Routage | DNS, load balancer, listeners, certificats TLS. |
| Observabilité | Alarmes CloudWatch, dashboards, log groups, alert rules. |
Lexique essentiel
| Terme | Rôle |
|---|---|
| Provider | Connecteur vers AWS, Azure, GCP, GitLab, Cloudflare, Hetzner, Kubernetes, etc. |
| Resource | Objet que Terraform crée, modifie ou supprime. |
| Data source | Objet existant que Terraform lit sans forcément le gérer. |
| Variable | Paramètre d’entrée permettant d’adapter le code à chaque environnement. |
| Output | Valeur exposée après exécution : IP, DNS, ARN, endpoint, ID. |
| State | Mémoire Terraform reliant le code aux ressources réellement créées. |
| Plan | Diff calculé avant modification réelle de l’infrastructure. |
| Apply | Application 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 à jourArchitecture 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/Découpage par domaine
| Domaine | Contenu typique | Risque principal |
|---|---|---|
| network | VPC, subnets, routes, NAT, peering. | Couper tout le trafic si erreur. |
| security | IAM, security groups, KMS, firewall. | Ouvrir trop large ou bloquer la prod. |
| app | Compute, containers, load balancer, autoscaling. | Indisponibilité applicative. |
| data | RDS, Redis, buckets, volumes. | Perte de données ou recréation accidentelle. |
| monitoring | Alarmes, 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 utilesFichiers 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| Fichier | Rôle |
|---|---|
versions.tf | Contraintes de versions Terraform et providers. |
providers.tf | Configuration des providers : AWS, Azure, GitLab, etc. |
backend.tf | Configuration du stockage distant du state. |
variables.tf | Déclaration des paramètres d’entrée. |
main.tf | Ressources principales ou appel aux modules. |
locals.tf | Valeurs calculées, conventions de nommage, tags communs. |
outputs.tf | Valeurs exposées après création. |
terraform.tfvars | Valeurs 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
}
}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
| Provider | Usage courant |
|---|---|
| AWS | VPC, EC2, ECS, EKS, RDS, IAM, S3, CloudWatch, Route53. |
| Azure | Resource groups, VNets, AKS, Key Vault, SQL, App Services. |
| Google Cloud | VPC, GKE, Cloud SQL, IAM, Cloud Storage, Cloud Run. |
| Kubernetes | Namespaces, secrets, config maps, services, deployments. |
| GitLab | Projects, variables CI/CD, runners, groups, access tokens. |
| Cloudflare | DNS, WAF, CDN, firewall rules. |
| Datadog | Dashboards, monitors, alerting, SLO. |
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
| Risque | Prévention |
|---|---|
| Version non maîtrisée | Fixer les versions dans required_providers. |
| Credentials trop larges | Utiliser des droits limités par environnement. |
| Provider upgrade cassant | Tester 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 validationResources 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"]
}
}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ément | Terraform est propriétaire ? | Exemple |
|---|---|---|
| Resource | Oui | Créer un security group. |
| Data source | Non | Lire une AMI Ubuntu existante. |
Cycle de dépendances
data source
│
▼
récupère une information existante
│
▼
resource
│
▼
utilise cette information pour créer un objetVariables, 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"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ée | Conseil |
|---|---|
| Mot de passe | Ne pas mettre en clair dans Git. |
| Token API | Utiliser variables CI/CD protégées ou secret manager. |
| Clé privée | Éviter dans Terraform si possible. |
| Endpoint public | Output acceptable si non sensible. |
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
| Commande | Rôle |
|---|---|
terraform init | Initialise le backend, télécharge les providers et modules. |
terraform fmt | Formate le code selon les conventions Terraform. |
terraform validate | Vérifie la cohérence syntaxique et structurelle. |
terraform plan | Affiche ce qui va changer sans modifier l’infrastructure. |
terraform apply | Applique réellement les changements. |
terraform destroy | Détruit les ressources gérées. À éviter en production sauf cas maîtrisé. |
Lire un plan Terraform
| Symbole | Signification | Niveau 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-applyState 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
| Sujet | Risque | Bonne pratique |
|---|---|---|
| State local | Perte, divergence, conflit entre développeurs. | Utiliser un backend distant. |
| Concurrence | Deux 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. |
| Suppression | Terraform 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
}
}State locking
Pipeline A lance terraform apply
│
▼
verrouillage du state
│
├── Pipeline A peut écrire
└── Pipeline B doit attendre
│
▼
fin du apply
│
▼
déverrouillage du stateCommandes liées au state
| Commande | Usage |
|---|---|
terraform state list | Lister les ressources connues du state. |
terraform state show | Inspecter une ressource du state. |
terraform import | Rattacher une ressource existante au state. |
terraform state rm | Retirer une ressource du state sans la supprimer réellement. |
terraform state mv | Déplacer ou renommer une ressource dans le state. |
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 / AlertingCe que Terraform peut gérer
| Composant | Terraform gère |
|---|---|
| Réseau | VPC, subnets privés/publics, NAT, routes. |
| Sécurité | Security groups, IAM roles, policies. |
| Application | Load balancer, target groups, compute, autoscaling. |
| Database | Instance RDS, subnet group, backup window, monitoring. |
| DNS | Records 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ôle | Pourquoi |
|---|---|
| Plan relu | Éviter suppression ou recréation involontaire. |
| State verrouillé | Empêcher deux apply concurrents. |
| Variables protégées | Limiter l’exposition des credentials. |
| Rollback ou mitigation | Rétablir vite en cas d’incident. |
| Monitoring actif | Voir rapidement si le changement dégrade la production. |
Erreurs courantes et réflexes professionnels
| Erreur | Cause probable | Risque | Réflexe professionnel |
|---|---|---|---|
| Provider conflict | Versions non figées ou incompatibles. | Plan instable ou comportement imprévu. | Fixer les versions dans required_providers. |
| State lock | Un autre job Terraform utilise le state. | Apply concurrent ou state corrompu. | Identifier le job actif, attendre, ne pas forcer sans analyse. |
| Drift | Modification manuelle dans la console cloud. | Terraform veut annuler ou recréer des ressources. | Comparer, importer, corriger le code ou revenir à l’état attendu. |
| Permission denied | Credentials 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 exists | Objet déjà créé hors Terraform. | Duplication impossible ou conflit de nom. | Utiliser terraform import ou renommer proprement. |
| Plan wants to destroy | Changement 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 value | Variable 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 applyLifecycle utile
resource "aws_db_instance" "main" {
identifier = "${local.name_prefix}-db"
lifecycle {
prevent_destroy = true
}
}prevent_destroy est une ceinture de sécurité, pas une excuse pour ne pas relire le plan.Checklist professionnelle Terraform
Avant merge request
| Point | Validation |
|---|---|
| Format | terraform fmt -check -recursive passe correctement. |
| Validation | terraform validate ne remonte pas d’erreur. |
| Variables | Types, descriptions et validations définis. |
| Tags | Project, Environment, Owner, ManagedBy présents. |
| Sécurité | Pas de secret en clair, pas d’ouverture réseau dangereuse. |
| Modules | Inputs/outputs lisibles, README si module partagé. |
Avant apply production
| Point | Question à poser |
|---|---|
| Plan | Le plan a-t-il été relu par une autre personne ? |
| Destroy | Y a-t-il une suppression ou recréation ? Si oui, pourquoi ? |
| State | Le state est-il distant, verrouillé et protégé ? |
| Rollback | Existe-t-il une procédure de mitigation si problème ? |
| Monitoring | Les métriques et logs permettront-ils de voir l’impact ? |
| Fenêtre | Le changement est-il fait au bon moment opérationnel ? |
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 outputPourquoi 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.
Ce qu’un module doit apporter
| Objectif | Impact concret |
|---|---|
| Réutilisation | Le 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. |
| Standardisation | Nommage, tags, sécurité, logs et conventions sont homogènes. |
| Contrôle | Les variables exposées limitent ce que l’utilisateur du module peut modifier. |
| Maintenance | Une correction dans le module peut bénéficier à plusieurs environnements. |
| Audit | Les 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
└── dashboardsModule vs simple fichier Terraform
| Approche | Usage adapté | Limite |
|---|---|---|
| Fichier simple | Petit prototype, test local, ressource isolée. | Devient vite illisible en production. |
| Module local | Projet 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é. |
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/live décrivent les environnements réels.Root module vs child module
| Type | Rôle | Exemple |
|---|---|---|
| Root module | Point d’entrée exécuté par terraform plan/apply. | live/prod/app/ |
| Child module | Brique appelée par le root module. | modules/load-balancer |
| Shared module | Module partagé entre plusieurs repos ou équipes. | git::ssh://... |
| External module | Module 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
└── databaseExemple 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
}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ément | Bonne pratique |
|---|---|
| Inputs | Peu nombreux, typés, documentés, avec defaults raisonnables. |
| Outputs | Limités aux valeurs nécessaires aux autres modules ou à l’exploitation. |
| Nommage | Prévisible : projet, environnement, composant, région. |
| Tags | Appliqués partout quand le provider le permet. |
| Sécurité | Pas d’accès public par défaut, pas de droits trop larges. |
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/CDExemple 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 principal | Définir le CIDR global de l’environnement. |
| Subnets publics | Load balancers, NAT gateways, bastions éventuels. |
| Subnets privés | Applications, workers, bases de données, caches. |
| Routes | Accès internet, NAT, peering, transit gateway. |
| Outputs | VPC 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
└── SearchOutputs 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
}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
| Composant | Rôle |
|---|---|
| Compute | EC2, ECS service, EKS workload, instance group. |
| Load balancer | Entrée HTTP/HTTPS, health checks, target groups. |
| Autoscaling | Adapter la capacité selon CPU, mémoire, trafic. |
| Logs | Configurer log group, rétention, format. |
| Monitoring | Alarmes 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 internesOutputs 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
}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ètre | Pourquoi c’est important |
|---|---|
| engine / version | PostgreSQL, MySQL, MariaDB et version exacte. |
| instance class | Dimensionnement CPU/RAM. |
| storage | Capacité, type disque, autoscaling éventuel. |
| backup retention | Durée de conservation des sauvegardes. |
| multi_az | Résilience en cas de panne de zone. |
| deletion protection | Protection contre suppression accidentelle. |
| maintenance window | Contrô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 protectionProtections recommandées
| Protection | But |
|---|---|
deletion_protection | Empêcher suppression accidentelle. |
prevent_destroy | Bloquer destruction Terraform non voulue. |
| backups | Permettre restauration après incident. |
| private subnets | Éviter exposition Internet. |
| restricted security group | Limiter les clients autorisés. |
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ègle | Exigence |
|---|---|
| Least privilege | Ne pas créer des IAM policies trop larges par défaut. |
| No public by default | Un module ne doit pas exposer Internet sauf choix explicite. |
| Encryption | Activer chiffrement pour stockage, logs et bases si disponible. |
| No hardcoded secrets | Pas de mot de passe, token ou clé dans le code Terraform. |
| Audit tags | Tags Owner, Environment, ManagedBy, CostCenter si besoin. |
| Safe defaults | Les 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é
| Outil | Usage |
|---|---|
| Checkov | Analyse IaC pour mauvaises pratiques sécurité. |
| tfsec | Scan sécurité Terraform. |
| Trivy | Scan IaC, images containers et dépendances. |
| Vault | Gestion centralisée des secrets. |
| AWS Secrets Manager | Secrets managés côté AWS. |
| GitLab protected variables | Injection sécurisée en pipeline CI/CD. |
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
| Source | Usage | Risque |
|---|---|---|
| Local path | Monorepo, projet simple, modules internes. | Pas de version explicite si même repo. |
| Git tag | Module partagé et versionné. | Nécessite release discipline. |
| Registry | Standard 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.2Compatibilité
| Type de changement | Version conseillée |
|---|---|
| Correction interne sans changement d’API | Patch : v1.4.1 vers v1.4.2 |
| Ajout d’option rétrocompatible | Minor : v1.4.2 vers v1.5.0 |
| Suppression variable / changement breaking | Major : v1.x vers v2.0.0 |
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 releaseExemple 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: falseTests pratiques de module
| Test | But |
|---|---|
| Format | Code homogène et lisible. |
| Validate | Détecter erreurs Terraform évidentes. |
| Security scan | Identifier ports ouverts, chiffrement manquant, IAM trop large. |
| Example plan | Vérifier qu’un appel standard du module produit un plan cohérent. |
| Docs generation | Générer README variables / outputs avec terraform-docs. |
Outils liés
| Outil | Utilité |
|---|---|
| terraform-docs | Génère la documentation inputs / outputs. |
| tflint | Lint Terraform avancé. |
| Checkov | Policies sécurité IaC. |
| Terratest | Tests d’intégration Terraform en Go. |
Anti-patterns des modules Terraform
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| Module géant unique | Impossible à relire, à tester et à faire évoluer. | Découper par responsabilité : network, compute, data, security. |
| Variables sans type | Les erreurs arrivent tard, souvent au plan ou à l’apply. | Types explicites, validation, defaults sûrs. |
| Module trop flexible | Chaque équipe peut créer une variante dangereuse. | Exposer uniquement les options nécessaires et sûres. |
| Secrets dans tfvars | Risque de fuite Git, logs, artefacts CI/CD. | Secret manager ou variables protégées CI/CD. |
| Outputs trop bavards | Exposition d’informations internes ou sensibles. | Outputs minimaux, sensitive = true si nécessaire. |
| Production sur branche main | Une modification module peut impacter prod sans contrôle de version. | Utiliser tags ou releases versionnées. |
| Pas de README | Le module devient incompréhensible pour les nouveaux DevOps. | Documenter usage, inputs, outputs, exemples et limitations. |
| Pas de garde-fou destruction | Risque 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 variablesBon 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éeChecklist de qualité d’un module Terraform
Checklist technique
| Point | Validation attendue |
|---|---|
| Responsabilité unique | Le module fait une chose claire : réseau, compute, database, etc. |
| Variables typées | Toutes les variables ont un type explicite. |
| Descriptions | Inputs et outputs sont documentés. |
| Validations | Les valeurs risquées sont contrôlées. |
| Defaults sûrs | Aucun accès public ou droit large par défaut. |
| Tags | Tags standards appliqués partout où possible. |
| Outputs minimaux | Le module expose uniquement ce qui est nécessaire. |
| README | Usage, exemples, variables, outputs, limites. |
Checklist production
| Point | Question à poser |
|---|---|
| Destruction | Le module peut-il supprimer une ressource critique ? |
| Réseau | Expose-t-il quelque chose sur Internet par défaut ? |
| IAM | Crée-t-il des permissions trop larges ? |
| Secrets | Un secret peut-il finir dans Git, logs ou state ? |
| State | Le module est-il découpé pour éviter un state énorme ? |
| Monitoring | Le module crée-t-il les logs/alarms nécessaires ? |
| Versioning | La production consomme-t-elle une version stable ? |
| Rollback | Existe-t-il une stratégie en cas de mauvais changement ? |
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 validateLe 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.
Ce que contient typiquement le state
| Élément | Exemple | Sensibilité |
|---|---|---|
| IDs provider | ID d’instance, ARN IAM, ID security group. | Moyenne |
| Attributs ressources | IP privée, endpoint DB, DNS load balancer. | Moyenne à forte |
| Dépendances | Relation entre réseau, compute et database. | Faible à moyenne |
| Valeurs sensibles | Mot de passe, token, secret selon provider/module. | Forte |
| Outputs | Valeurs 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 dimensionsPourquoi le state est indispensable
| Besoin | Rôle du state |
|---|---|
| Suivi des ressources | Savoir quelles ressources appartiennent à Terraform. |
| Diff précis | Comparer l’état souhaité avec l’état connu. |
| Gestion des dépendances | Comprendre l’ordre de création, modification ou destruction. |
| Outputs | Partager certaines valeurs entre modules ou stacks. |
| Collaboration | Permettre à une équipe de travailler sur la même infrastructure. |
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
| Mode | Usage | Limite |
|---|---|---|
| Local | Formation, test personnel, prototype jetable. | Risque de perte, conflit, commit accidentel. |
| S3 + DynamoDB | Standard fréquent sur AWS. | Nécessite sécurisation bucket/table. |
| GitLab managed state | Pratique avec GitLab CI/CD. | Dépend de la plateforme GitLab. |
| Terraform Cloud / Enterprise | Collaboration, policy, remote runs, audit. | Solution plus structurée, parfois payante. |
| Azure Storage / GCS | Backends 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
}
}Ce que doit garantir le backend
| Garantie | Pourquoi |
|---|---|
| Centralisation | Toute l’équipe et la CI/CD utilisent la même source de vérité. |
| Locking | Empêcher deux apply simultanés sur le même state. |
| Versioning | Permettre restauration après corruption ou erreur humaine. |
| Chiffrement | Protéger données internes et secrets potentiels. |
| Contrôle d’accès | Limiter lecture/écriture aux pipelines et admins autorisés. |
| Audit | Savoir 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 proprementLocking : 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 proprementSans locking
| Situation | Risque |
|---|---|
| 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 abusif | Déverrouillage alors qu’un apply est encore actif. |
Que faire en cas de state lock ?
| Étape | Action correcte |
|---|---|
| 1. Identifier | Regarder quel pipeline ou utilisateur détient le lock. |
| 2. Attendre | Si l’apply est actif, ne rien forcer. |
| 3. Vérifier | Confirmer que le job est terminé ou mort. |
| 4. Déverrouiller | Utiliser force-unlock seulement si le lock est orphelin. |
| 5. Replanifier | Relancer terraform plan avant tout nouvel apply. |
Commande de dernier recours
terraform force-unlock LOCK_ID
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 foisIsolation 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
└── monitoringBonne approche
States séparés
│
├── dev/network
├── dev/app
├── dev/data
│
├── staging/network
├── staging/app
├── staging/data
│
├── prod/network
├── prod/app
└── prod/dataDécoupage recommandé
| State | Contenu | Fréquence de changement |
|---|---|---|
prod/network | VPC, subnets, routes, NAT. | Rare |
prod/security | IAM, KMS, security groups globaux. | Faible à moyenne |
prod/app | Compute, load balancer, autoscaling. | Moyenne à forte |
prod/data | Databases, caches, buckets critiques. | Rare et sensible |
prod/monitoring | Dashboards, 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
}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
| Risque | Conséquence | Protection |
|---|---|---|
| Commit Git | Fuite durable dans l’historique. | .gitignore, secret scanning, hooks. |
| Bucket trop ouvert | Lecture complète de l’infra. | IAM strict, bucket policy, audit logs. |
| Pas de chiffrement | Exposition en cas de fuite stockage. | Chiffrement côté backend. |
| Accès CI trop large | Pipeline compromis = state compromis. | Rôles dédiés, variables protégées, environnements protégés. |
| Outputs sensibles | Secrets 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.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ôle | Niveau pro attendu |
|---|---|
| Chiffrement | State chiffré au repos. |
| Versioning | Historique récupérable en cas d’erreur. |
| IAM | Lecture/écriture limitée aux rôles nécessaires. |
| Audit logs | Traçabilité des accès au backend. |
| Protected variables | Credentials injectés uniquement sur branches/environnements autorisés. |
| Rotation | Rotation 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 variablesDrift : 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.smallCauses fréquentes
| Cause | Exemple | Risque |
|---|---|---|
| ClickOps | Modification console AWS hors Terraform. | Plan inattendu. |
| Hotfix urgence | Ouverture temporaire d’un security group. | Dette de sécurité. |
| Suppression externe | Ressource supprimée par erreur hors Terraform. | Recréation ou erreur apply. |
| Import incomplet | Ressource existante rattachée partiellement. | Diff permanent. |
| Provider change | Nouvelle 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écisionCommandes utiles
terraform plan
terraform plan -refresh-only
terraform apply -refresh-only
terraform state list
terraform state show RESOURCE_NAMEPolitique anti-drift
| Interdire ClickOps | Sauf urgence documentée. |
| Plan régulier | Détection proactive des écarts. |
| Audit cloud | Identifier les modifications hors pipeline. |
| Runbook hotfix | Tout 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
| Commande | Usage | Danger |
|---|---|---|
terraform import | Rattacher une ressource existante au state. | Import incomplet si le code ne correspond pas. |
terraform state mv | Déplacer ou renommer une ressource dans le state. | Erreur de mapping. |
terraform state rm | Retirer une ressource du state sans la supprimer. | Terraform ne la gère plus. |
terraform state show | Inspecter une ressource connue. | Peut afficher données sensibles. |
terraform state pull | Exporter 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 planRenommer 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.applicationProcessus 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érationstate 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
| Étape | Réaction |
|---|---|
| Détection | Un fichier .tfstate apparaît dans le repo. |
| Risque | Fuite d’informations internes ou secrets. |
| Action immédiate | Supprimer 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 planScénario 3 : mauvais state utilisé
| Cause | Conséquence | Prévention |
|---|---|---|
| Backend mal configuré | Plan prod exécuté sur state staging ou inversement. | Clés backend explicites, pipeline par environnement. |
| Workspace mal choisi | Changements appliqués au mauvais contexte. | Éviter workspaces pour séparation critique si équipe peu mature. |
| Variables mélangées | Ressources prod avec paramètres dev. | tfvars contrôlés et environnements protégés. |
Scénario 4 : state corrompu ou perdu
- Stopper les applies immédiatement.
- Récupérer une version précédente du backend.
- Comparer avec l’infrastructure réelle.
- Restaurer le state si possible.
- Importer manuellement les ressources si nécessaire.
- Documenter la cause et renforcer les protections.
Outils liés au state, drift et sécurité Terraform
Outils Terraform natifs
| Outil / commande | Utilité |
|---|---|
terraform state list | Voir toutes les ressources connues du state. |
terraform state show | Inspecter une ressource précise. |
terraform plan -refresh-only | Observer les écarts entre state et cloud réel. |
terraform import | Rattacher une ressource existante. |
terraform force-unlock | Déverrouiller un lock orphelin. |
terraform output | Afficher 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.jsonOutils complémentaires
| Outil | Usage |
|---|---|
| GitLab CI/CD | Contrôler plans/applies et protéger environnements. |
| Terraform Cloud | Remote state, runs, policies, audit, collaboration. |
| Atlantis | Plans Terraform déclenchés depuis merge requests. |
| Spacelift | Orchestration IaC, drift detection, policies. |
| Checkov / tfsec / Trivy | Scan sécurité du code IaC. |
| CloudTrail / audit logs | Identifier les changements hors Terraform. |
| Cost tools | Estimer l’impact financier d’un plan. |
Anti-patterns State Terraform
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| State commité dans Git | Fuite de données sensibles et historique difficile à nettoyer. | Backend distant + .gitignore + secret scanning. |
| Un state pour tout | Blast radius énorme, plans lents, verrou global. | Découper par environnement et domaine. |
| Pas de locking | Risque d’applies concurrents et state incohérent. | Backend avec verrouillage actif. |
| force-unlock réflexe | Peut casser un apply encore actif. | Vérifier pipeline/job avant toute action. |
| ClickOps permanent | Drift permanent et Terraform devient imprévisible. | Tout changement durable revient dans le code. |
| Outputs sensibles | Secrets visibles dans logs ou autres states. | Outputs minimaux et marqués sensitive si nécessaire. |
| Manipulation state sans backup | Perte de mapping ou destruction involontaire future. | Sauvegarde, revue, plan post-opération. |
| Workspace utilisé pour tout | Confusion 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ésModèle professionnel
remote backend
│
├── state chiffré
├── versioning
├── locking
├── IAM strict
├── audit logs
└── séparation env/domaineChecklist professionnelle State Terraform
Checklist backend
| Point | Validation attendue |
|---|---|
| Backend distant | Le state n’est pas local en production. |
| Locking | Deux apply concurrents sont empêchés. |
| Versioning | Une version précédente du state peut être restaurée. |
| Chiffrement | Le state est chiffré au repos. |
| Accès limité | Seuls les rôles autorisés peuvent lire/écrire. |
| Audit | Les accès au backend sont traçables. |
| Backup | Procédure de récupération connue et testée. |
Checklist isolation
| Un state par environnement | Dev, staging et prod séparés. |
| Un state par domaine sensible | Network, app, data séparés si nécessaire. |
| Outputs limités | Remote state expose uniquement le nécessaire. |
| Pas de state énorme | Plan lisible et verrouillage limité. |
Checklist avant apply production
| Question | Pourquoi |
|---|---|
| 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. |
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_IDGitLab 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.
Ce que GitLab apporte à Terraform
| Besoin infra | Réponse GitLab CI/CD |
|---|---|
| Standardiser les commandes | Les mêmes jobs exécutent toujours fmt, validate, plan. |
| Tracer les changements | Chaque pipeline est lié à un commit, une branche, une MR et un utilisateur. |
| Contrôler la production | Branches protégées, environnements protégés, jobs manuels, approvals. |
| Sécuriser les secrets | Variables masked/protected, scopes par environnement. |
| Conserver les preuves | Artefacts de plan, logs de pipeline, historique d’exécution. |
| Réduire les erreurs humaines | Moins 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 besoinGitLab 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.
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
└── alertesStages typiques
| Stage | But | Bloquant ? |
|---|---|---|
fmt | Vérifier le format Terraform. | Oui |
validate | Valider syntaxe, providers, modules. | Oui |
security | Détecter ports ouverts, IAM trop larges, secrets. | Oui ou warning selon maturité. |
plan | Afficher exactement ce que Terraform veut changer. | Oui |
review | Relire le plan et décider. | Oui pour prod |
apply | Modifier réellement l’infrastructure. | Manuel/protégé pour prod |
post_check | Vérifier santé réelle après changement. | Oui si critique |
Politique par environnement
| Environnement | Plan | Apply |
|---|---|---|
| dev | Automatique | Automatique ou manuel simple |
| staging | Automatique | Manuel avec validation équipe |
| prod | Automatique, archivé | Manuel, protégé, approbation requise |
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ément | Rôle |
|---|---|
TF_IN_AUTOMATION | Indique à Terraform qu’il tourne dans une CI. |
TF_INPUT=false | Évite les prompts interactifs bloquants. |
artifacts | Conserve le plan binaire et le plan lisible. |
when: manual | Force un clic humain pour appliquer en production. |
environment | Lie 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.
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
| Type | Usage | Risque |
|---|---|---|
| Shared runner | Jobs génériques, projets peu sensibles. | Moins de contrôle sur l’environnement. |
| Group runner | Standard d’équipe ou de département. | Attention aux droits transverses. |
| Project runner | Projet spécifique, meilleur cloisonnement. | Maintenance dédiée. |
| Protected runner | Branches/tags protégés seulement. | Recommandé pour production. |
| Self-hosted runner | Contrô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 tfplanArchitecture 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 prodRisques runner
| Risque | Prévention |
|---|---|
| Runner non protégé | Limiter les jobs prod aux branches protégées. |
| Credentials trop larges | IAM minimal par environnement. |
| Logs exposant secrets | Variables masked, pas de echo de secrets. |
| Runner partagé trop large | Runner dédié infra pour jobs sensibles. |
| Image CI non maîtrisée | Images versionnées et scannées. |
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
| Type | Usage | Protection recommandée |
|---|---|---|
| Cloud credentials | Accès AWS, Azure, GCP. | Masked + protected + scope environnement. |
| Terraform vars | TF_VAR_* pour injecter variables Terraform. | Protected si prod. |
| Backend config | Bucket, key, région, workspace. | Variables non sensibles mais contrôlées. |
| Tokens outils | Checkov, Vault, GitLab API, registry. | Masked + rotation régulière. |
| Feature flags | Activer 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 GitLab | Rôle |
|---|---|
| Masked | Masque la valeur dans les logs. |
| Protected | Disponible seulement pour branches/tags protégés. |
| Environment scope | Limite la variable à un environnement précis. |
| File variable | Stocke 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 GitReview 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
| Point | Question à poser | Danger |
|---|---|---|
| Destroy | Y a-t-il des suppressions ? | Perte de service ou données. |
| Replace | Une ressource est-elle recréée ? | Downtime, perte d’IP, remplacement DB. |
| Security group | Un port est-il ouvert trop largement ? | Exposition sécurité. |
| IAM | Une policy donne-t-elle trop de droits ? | Escalade de privilèges. |
| Database | Backup, storage, deletion protection changent-ils ? | Risque data. |
| Scope | Le plan concerne-t-il le bon environnement ? | Erreur dev/prod. |
| Secrets | Une valeur sensible apparaît-elle ? | Fuite logs/artifacts. |
destroy ou replace en production exige une justification explicite.Lecture du plan
| Symbole | Signification | Ré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 rejetCommentaire 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 applicatifsApply 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-fou | But |
|---|---|
| Protected branch | Empêcher un apply depuis une branche non validée. |
| Protected environment | Limiter qui peut déployer en production. |
| Manual job | Forcer une décision humaine. |
| Approvals | Exiger validation d’un ou plusieurs responsables. |
| Protected variables | Rendre 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
- protectedApply 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-checksAvant 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. |
-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
| Situation | Réaction possible | Risque |
|---|---|---|
| Security group trop restrictif | Revenir au commit précédent ou hotfix Terraform. | Service inaccessible. |
| IAM policy cassée | Restaurer policy précédente. | Jobs/applications bloqués. |
| Load balancer mal configuré | Revenir listener/target group. | Downtime web. |
| Database modifiée | Mitigation, restore ou correction manuelle contrôlée. | Risque data élevé. |
| Ressource supprimée | Recré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 serviceMitigation vs rollback
| Approche | Quand l’utiliser |
|---|---|
| Rollback | Quand revenir à l’état précédent est sûr et rapide. |
| Mitigation | Quand il faut restaurer le service sans forcément revenir totalement en arrière. |
| Hotfix Terraform | Quand une correction rapide doit rester versionnée. |
| Action manuelle d’urgence | Dernier 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.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ôle | Pourquoi |
|---|---|
| Branches protégées | Empêcher un apply prod depuis une branche arbitraire. |
| Variables protégées | Limiter les credentials prod au contexte autorisé. |
| Environnements protégés | Limiter 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 IaC | Détecter mauvaises pratiques avant merge. |
| Secret detection | Empê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
- prodThreat 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 logsOutils sécurité liés
| Outil | Usage |
|---|---|
| Checkov | Scan Terraform et politiques cloud. |
| tfsec | Détection de mauvaises pratiques Terraform. |
| Trivy config | Scan IaC, containers, dépendances. |
| GitLab Secret Detection | Détecter secrets committés. |
| Vault / Secrets Manager | Gestion des secrets hors GitLab si nécessaire. |
Debug GitLab CI/CD Infra
Problèmes fréquents
| Symptôme | Cause probable | Réflexe |
|---|---|---|
| Job pending | Aucun runner disponible ou tags incorrects. | Vérifier runners, tags, protection. |
| Variable vide | Variable protected non disponible sur branche non protégée. | Contrôler protected branch et scope. |
| terraform init échoue | Backend inaccessible ou credentials invalides. | Vérifier IAM, backend, réseau. |
| State lock | Autre pipeline actif ou lock orphelin. | Identifier job actif avant force-unlock. |
| Plan différent local/CI | Versions Terraform/providers ou variables différentes. | Pinner versions, comparer variables. |
| Apply refuse permission | Rôle cloud insuffisant. | Corriger IAM avec moindre privilège. |
| Artifact manquant | Mauvais 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_IDMé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écessaireecho $SECRET pour debugger. Utiliser des tests indirects et des variables masquées.Checklist GitLab CI/CD Infrastructure
Checklist pipeline
| Point | Validation attendue |
|---|---|
| Stages séparés | fmt, 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 prod | Jamais 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ées | Masked, protected, scoped. |
| Scans sécurité | Checkov/tfsec/Trivy/secret detection selon contexte. |
Checklist avant apply production
| Question | Pourquoi |
|---|---|
| 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. |
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 listPourquoi 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.
Différences fondamentales
| Environnement | Objectif | Niveau de contrôle |
|---|---|---|
| Dev | Expérimenter, tester rapidement, casser sans impact client. | Faible à moyen, apply parfois semi-automatique. |
| Review app | Créer un environnement temporaire pour une merge request. | Automatique, durée limitée, ressources jetables. |
| Staging | Valider avant production dans un contexte réaliste. | Plan, revue, apply contrôlé. |
| Preprod | Répétition quasi identique à la production. | Contrôle fort, proche prod. |
| Prod | Servir 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érenteCe qu’il faut isoler
| Élément | Pourquoi 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. |
| Runners | Limiter les droits prod aux runners protégés. |
| Approvals | Appliquer un contrôle fort uniquement là où nécessaire. |
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é
| Env | Infrastructure | Données | Déploiement |
|---|---|---|---|
| Dev | Réduite, économique, flexible. | Fake data ou anonymisée. | Rapide, parfois automatique. |
| Review | Temporaire, détruite après MR. | Jeu minimal ou fixtures. | Automatique par MR. |
| Staging | Proche prod mais plus petit. | Anonymisée ou snapshot contrôlé. | Manuel ou semi-automatique. |
| Preprod | Très proche prod. | Anonymisée, volume représentatif. | Répétition avant prod. |
| Prod | Haute 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-apiArchitecture 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 incidentsStratégie cloud
| Approche | Avantage | Limite |
|---|---|---|
| Un compte cloud unique | Simple pour débuter. | Isolation faible si IAM mal géré. |
| Un compte par environnement | Isolation forte, très professionnel. | Plus d’administration. |
| Un projet cloud par env | Bon compromis sur GCP/GitLab. | Governance nécessaire. |
| Multi-account prod stricte | Sécurité et blast radius très contrôlés. | Complexité plus élevée. |
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é
| Git | Environnement | Pipeline | Droits |
|---|---|---|---|
feature/* | dev ou review app | fmt, validate, plan dev | Pas de secrets prod |
develop | dev partagé | plan/apply dev possible | Credentials dev |
release/* | staging | plan + apply manuel staging | Credentials staging |
main | production | plan prod + apply manuel | Credentials prod protégés |
tag v* | release production | dé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 manuelEnvironnements protégés GitLab
| Protection | Rôle |
|---|---|
| Protected branches | Empêcher push/merge non autorisé sur main. |
| Protected environments | Limiter qui peut exécuter le job prod. |
| Required approvals | Exiger validation avant merge ou deploy. |
| Scoped variables | Limiter secrets à production/staging/dev. |
| Runner tags | Associer les jobs sensibles aux runners protégés. |
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
| Variable | Scope | Protection |
|---|---|---|
AWS_ACCESS_KEY_ID_DEV | dev | Non prod, droits limités. |
AWS_ACCESS_KEY_ID_STAGING | staging | Protected si branche release protégée. |
AWS_ACCESS_KEY_ID_PROD | production | Masked + protected + environment scoped. |
TF_VAR_db_password | Selon env | Secret manager préférable. |
TF_VAR_instance_type | Selon env | Non 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 = 8Diagramme 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ègle | Pourquoi |
|---|---|
| Pas de secrets dans Git | Évite fuite durable dans l’historique. |
| Variables masked | Évite affichage dans logs. |
| Variables protected | Bloque l’accès depuis branches non protégées. |
| Scope environnement | Évite qu’un job dev lise un secret prod. |
| Rotation régulière | Réduit l’impact en cas de fuite. |
| Moindre privilège | Un credential dev ne doit jamais pouvoir agir sur prod. |
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 ?
| Domaine | Raison |
|---|---|
| network | Change rarement, impact fort. |
| app | Change plus souvent, impact applicatif. |
| data | Très sensible, protections renforcées. |
| monitoring | Peut évoluer sans toucher au compute. |
| security | IAM 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.tfstateRemote 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"
}
}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
| Env | Qui valide ? | Quand ? |
|---|---|---|
| Dev | Développeur ou DevOps responsable. | Si changement non sensible. |
| Staging | DevOps + tech lead si impact significatif. | Avant validation release. |
| Preprod | Tech lead, QA, DevOps. | Avant répétition prod. |
| Prod | DevOps senior, responsable plateforme, owner métier si nécessaire. | Avant apply. |
| Prod critique | Double 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-checksCritères Go / No-Go
| Critère | Go | No-Go |
|---|---|---|
| Plan | Compris, attendu, relu. | Destroy inexpliqué. |
| Rollback | Procédure claire. | Aucune mitigation. |
| Monitoring | Alertes et métriques prêtes. | Impact invisible. |
| Fenêtre | Moment acceptable. | Pic trafic ou période critique. |
| Sécurité | Scan OK ou risque accepté. | Secret exposé ou IAM trop large. |
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-checksPourquoi promouvoir progressivement ?
| Bénéfice | Explication |
|---|---|
| Détection précoce | Les erreurs apparaissent avant la production. |
| Plan plus fiable | Le changement a déjà été observé ailleurs. |
| Confiance équipe | Moins 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 productionArtefacts utiles à chaque étape
| Artefact | Utilité |
|---|---|
| Plan Terraform lisible | Review humaine. |
| Plan binaire | Apply exact du plan généré. |
| Rapport scan sécurité | Preuve de contrôle IaC. |
| Log de déploiement | Audit et diagnostic. |
| Résultat post-check | Validation santé après changement. |
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
| Env | Données recommandées | Risques |
|---|---|---|
| Dev local | Fixtures, 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. |
| Staging | Snapshot anonymisé représentatif. | Fausse validation si données trop petites. |
| Preprod | Données proches prod mais anonymisées. | Conformité, confidentialité. |
| Prod | Donné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 personnellesFlux de données sécurisé
Production database
│
▼
Export contrôlé
│
▼
Anonymisation / masking
│
▼
Validation sécurité
│
▼
Import staging
│
▼
Tests fonctionnels et performanceRègles professionnelles
| Pas de dump prod brut en local | Risque majeur de fuite. |
| Snapshots chiffrés | Protection pendant transfert et stockage. |
| Accès limité | Seules les personnes autorisées manipulent les exports. |
| Durée de vie limitée | Supprimer les exports temporaires. |
| Traçabilité | Savoir qui a extrait, transformé, importé. |
Incidents classiques liés aux environnements
Scénarios réels
| Incident | Cause | Prévention |
|---|---|---|
| Apply prod depuis feature branch | Variables prod non protégées. | Protected variables + protected branches. |
| State staging pointe vers prod | Backend key mal configurée. | Backend explicite + logs d’environnement. |
| Database prod utilisée en staging | Variable DB host incorrecte. | Secrets scopés + tests de garde-fou. |
| Runner dev possède droits prod | IAM trop large. | Runner dédié + rôle cloud dédié. |
| Staging trop différent de prod | Infra sous-dimensionnée ou config divergente. | Parité raisonnable sur composants critiques. |
| Données réelles en dev | Dump 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-fousGarde-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
fiAnti-patterns de gestion des environnements
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| Mêmes credentials partout | Un job dev peut modifier prod. | Credentials dédiés par environnement. |
| Un seul state global | Blast radius énorme et risque dev/prod. | State séparé par env et domaine. |
| Variables prod globales | Accessibles depuis mauvaises branches/jobs. | Variables masked, protected, scoped. |
| Staging symbolique | Ne valide pas les vrais risques prod. | Staging proche prod sur composants critiques. |
| Données prod brutes en dev | Risque de fuite et non-conformité. | Données synthétiques ou anonymisées. |
| Apply prod automatique | Aucun contrôle humain sur changement critique. | Apply manuel, approval, environnement protégé. |
| Branches non protégées | Merge ou deploy non contrôlé. | Protected branches + MR obligatoire. |
| Pas de convention de nommage | Confusion 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 manuellementBon 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éChecklist professionnelle de séparation des environnements
Checklist structure
| Point | Validation attendue |
|---|---|
| Branches | Mapping clair : feature/dev, release/staging, main/prod. |
| Variables | Variables séparées et scopées par environnement. |
| Credentials | Credentials cloud distincts par environnement. |
| State | State Terraform séparé par env et domaine critique. |
| Runners | Runner prod protégé, taggé et limité. |
| Nommage | Ressources préfixées par projet + environnement. |
| Données | Pas de données prod brutes hors prod. |
| Monitoring | Staging/prod ont des checks adaptés. |
Checklist production
| Question | Pourquoi |
|---|---|
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é. |
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-checksPourquoi 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.
Familles de secrets
| Secret | Exemple | Risque si fuite |
|---|---|---|
| Cloud credentials | AWS, Azure, GCP, Hetzner. | Contrôle infrastructure. |
| Terraform backend | Accès bucket state, GitLab state, Terraform Cloud token. | Lecture/modification du state. |
| Registry | Docker registry, GitLab registry, ECR. | Push d’images compromises. |
| SSH / deploy key | Clé privée serveur ou repo. | Accès serveur ou code source. |
| Database | Mot de passe PostgreSQL/MySQL/Redis. | Lecture ou modification de données. |
| API token | Cloudflare, 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 cloudObjectifs professionnels
| Réduire l’exposition | Secrets disponibles uniquement au moment et au job nécessaires. |
| Limiter le blast radius | Un secret dev ne doit pas agir sur prod. |
| Éviter le secret statique | Préférer credentials temporaires, OIDC, STS, Vault. |
| Tracer les usages | Audit cloud et GitLab pour savoir qui a fait quoi. |
| Permettre la révocation | Rotation documentée et rapide en cas de fuite. |
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
| Option | Rôle | À utiliser pour |
|---|---|---|
| Masked | Masque la valeur dans les logs. | Tokens, clés, mots de passe. |
| Protected | Disponible seulement pour branches/tags protégés. | Credentials production. |
| Environment scope | Limite une variable à un environnement GitLab. | Dev, staging, production. |
| File variable | Crée un fichier temporaire avec le contenu secret. | Kubeconfig, certificat, clé privée. |
| Group variable | Partage une variable sur plusieurs projets. | Standards d’équipe. |
| Project variable | Limite 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_passwordBon 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.yml | Le YAML est versionné dans Git. |
Pas de secret dans *.tfvars commité | Risque de fuite durable. |
Pas de secret dans echo | Les logs CI sont consultables et persistants. |
| Variables prod protected | Accès seulement depuis branches/tags protégés. |
| Variables prod scoped | Accès seulement pour l’environnement production. |
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é
| Secret | Scope | Disponible pour |
|---|---|---|
AWS_ACCESS_KEY_ID_DEV | development | Jobs dev uniquement. |
AWS_ACCESS_KEY_ID_STAGING | staging | Jobs staging uniquement. |
AWS_ACCESS_KEY_ID_PROD | production | Jobs production uniquement. |
GITLAB_TOKEN_READONLY | global ou projet | Lecture API limitée. |
REGISTRY_PUSH_TOKEN | build | Jobs build/publish. |
Séparation branche / environnement
feature/*
│
└── pas de secrets prod
develop
│
└── secrets dev
release/*
│
└── secrets staging
main
│
└── secrets production
├── masked
├── protected
└── environment scopedGarde-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
fiErreur 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.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
| Approche | Avantage | Risque |
|---|---|---|
| Clé statique | Simple à configurer. | Fuite durable si compromise. |
| OIDC | Credentials temporaires, contextuels, révocables. | Configuration initiale plus avancée. |
| Vault dynamique | Secrets 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 automatiquementExemple 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
| Condition | But |
|---|---|
| Projet GitLab exact | Empêcher un autre projet d’assumer le rôle. |
| Branche protégée | Limiter la production à main ou tags release. |
| Environnement | Différencier dev, staging, prod. |
| Audience | Empêcher réutilisation du token ailleurs. |
| Durée courte | Limiter la fenêtre d’exploitation. |
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ôle | Droits | Usage |
|---|---|---|
| plan-dev | Lecture + droits limités dev. | Plan et tests dev. |
| apply-dev | Écriture dev limitée. | Apply dev. |
| plan-prod | Lecture production. | Générer plan production. |
| apply-prod | Écriture production limitée aux ressources nécessaires. | Apply manuel protégé. |
| break-glass | Droits é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/STSVault, 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
| Solution | Usage | Points forts |
|---|---|---|
| HashiCorp Vault | Secrets centralisés, credentials dynamiques. | Très puissant, multi-cloud, audit. |
| AWS Secrets Manager | Secrets applicatifs et rotation AWS. | Intégration AWS native. |
| AWS SSM Parameter Store | Paramètres et secrets simples. | Simple, économique, IAM natif. |
| Azure Key Vault | Secrets, certificats, clés Azure. | Intégration Azure. |
| GCP Secret Manager | Secrets GCP versionnés. | Intégration IAM GCP. |
| GitLab CI variables | Secrets 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 GitRotation
| Secret | Fréquence indicative | Déclencheur urgent |
|---|---|---|
| Cloud access key | 30 à 90 jours si statique. | Suspicion de fuite. |
| API token | Selon criticité. | Log exposé ou repo compromis. |
| Database password | Planifiée et testée. | Fuite, départ collaborateur, incident. |
| SSH key | À éviter en CI si possible. | Serveur ou runner compromis. |
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
- printenvMeilleure approche
script:
- echo "Terraform plan started"
- terraform plan -var-file="prod.tfvars"
- echo "Terraform plan completed"Risques logs
| Risque | Exemple | Prévention |
|---|---|---|
| Echo secret | echo $TOKEN | Interdire affichage secrets. |
| Mode debug | set -x | Désactiver autour des commandes sensibles. |
| Terraform output | Output contenant mot de passe. | sensitive = true, outputs minimaux. |
| Erreur outil | Stack trace imprimant config. | Tester outils, filtrer logs, limiter secrets. |
| Artifact involontaire | Archive 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"
fiTerraform, 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
}Ce qu’il faut protéger
| Remote state | Chiffrement, IAM strict, audit, versioning. |
| Artifacts plan | Ne pas archiver des plans contenant des secrets non maîtrisés. |
| tfvars | Ne pas commiter les fichiers contenant secrets. |
| Outputs | Limiter 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 bruteExemple : 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
| Question | Ré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. |
Incidents de secrets : détection, réponse, rotation
Scénarios classiques
| Incident | Cause | Impact possible |
|---|---|---|
| Secret commité dans Git | .env, tfvars, clé privée ajoutée par erreur. | Fuite durable dans historique. |
| Secret affiché dans logs | echo, env, debug shell. | Consultation par utilisateurs GitLab. |
| Runner compromis | Runner partagé ou mal isolé. | Vol de variables et tokens. |
| Clé cloud trop large | IAM admin dans CI. | Contrôle complet du compte cloud. |
| Artifact sensible | Plan/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éventionRunbook 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 admin | Critique | Révocation immédiate + audit cloud. |
| DB prod password | Critique | Rotation + analyse accès. |
| Token staging | Élevée | Rotation + vérifier absence prod. |
| Token lecture non-prod | Moyenne | Rotation planifiée rapide. |
Anti-patterns secrets & sécurité CI
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| Secret dans Git | Fuite durable dans l’historique. | Variables GitLab, Vault, Secret Manager. |
| Variables prod globales | Accessibles par jobs non-prod ou branches non protégées. | Masked + protected + environment scoped. |
| IAM admin en CI | Un pipeline compromis contrôle tout. | Rôles par environnement et moindre privilège. |
| Clés statiques longues durées | Fuite exploitable longtemps. | OIDC, STS, credentials temporaires. |
echo $SECRET | Secret exposé dans logs. | Tester présence sans afficher valeur. |
set -x partout | Commandes et variables sensibles affichées. | Debug ciblé, désactivé autour secrets. |
| Artifacts trop larges | Archive de fichiers sensibles. | Artifacts explicitement listés et contrôlés. |
| Pas de rotation | Secret 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'auditModè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éChecklist professionnelle secrets & sécurité CI
Checklist GitLab
| Point | Validation attendue |
|---|---|
| Masked | Les secrets sont masqués dans les logs. |
| Protected | Les secrets prod sont limités aux branches/tags protégés. |
| Environment scoped | Les variables prod ne sont disponibles qu’en production. |
| Runner protégé | Les jobs prod tournent sur un runner contrôlé. |
| Artifacts contrôlés | Aucun .env, .tfstate ou secret dans les artifacts. |
| Secret detection | Scan activé sur MR et branches principales. |
| Logs sobres | Pas de env, printenv, echo $SECRET. |
Checklist IAM
| Rôle dédié CI | Pas de clé personnelle dans la pipeline. |
| Moindre privilège | Actions et ressources limitées. |
| Séparation env | Dev, staging, prod ont des rôles différents. |
| Credentials courts | OIDC/STS si possible. |
| Audit | CloudTrail/audit logs activés. |
| Rotation | Procédure documentée et testée. |
Checklist Terraform
| Question | Ré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. |
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 .envDé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.
Les 6 étapes d’un changement infra
| Étape | But | Sortie attendue |
|---|---|---|
| Préparation | Comprendre besoin, impact, risque. | Ticket ou change request clair. |
| Développement | Modifier Terraform ou pipeline. | Branche Git dédiée. |
| Validation | fmt, validate, security, plan. | Pipeline vert + plan lisible. |
| Review | Relire le plan et les risques. | Approval ou corrections. |
| Apply | Appliquer dans le bon contexte. | Infra modifiée proprement. |
| Vérification | Contrô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 / documentationDifférence entre app deploy et infra deploy
| Type | Rollback | Risque |
|---|---|---|
| Déploiement applicatif | Souvent revenir à l’image/version précédente. | Bug applicatif, régression fonctionnelle. |
| Déploiement infra | Parfois revenir au commit précédent, parfois mitigation. | Réseau, sécurité, données, disponibilité. |
Workflow propre de déploiement infrastructure
Workflow standard production
- Créer une demande de changement ou ticket technique.
- Décrire le besoin, le périmètre et le risque.
- Créer une branche Git dédiée.
- Modifier le code Terraform ou la configuration CI/CD.
- Lancer
terraform fmt,validate, scan sécurité etplan. - Relire le plan en merge request.
- Identifier destructions, remplacements, ouvertures réseau, IAM, database.
- Obtenir approval selon criticité.
- Appliquer dans une fenêtre adaptée.
- Vérifier santé cloud, applicative, logs, métriques et alertes.
- Documenter résultat, anomalies et suites éventuelles.
Pipeline type
MR pipeline
│
├── lint
├── validate
├── security
└── plan
│
▼
Review humaine
│
▼
Merge vers main
│
▼
Production pipeline
│
├── plan final
├── approval
├── apply manuel
└── post-checksResponsabilités
| Acteur | Responsabilité |
|---|---|
| Auteur | Prépare changement, plan, rollback et documentation. |
| Reviewer DevOps | Relit Terraform, plan, state, impact et sécurité. |
| Tech lead | Valide impact applicatif ou architecture. |
| Security | Valide IAM, exposition réseau, secrets si nécessaire. |
| Incident/on-call | Surveille après apply si changement critique. |
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.Classification du risque
| Niveau | Exemples | Contrôle |
|---|---|---|
| Faible | Tags, dashboard, alarme non critique. | Review simple. |
| Moyen | Autoscaling, security group interne, compute. | Review + staging. |
| Élevé | Load balancer, DNS, IAM, réseau. | Approval + fenêtre. |
| Critique | Database, 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. |
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.txtLecture du plan
| Symbole | Signification | Ré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. |
destroy ou replace en production ne doit passer sans justification claire.Checklist de review du plan
| Zone | À vérifier |
|---|---|
| Scope | Le plan touche bien le bon environnement et le bon domaine. |
| Network | Pas d’ouverture large non prévue, routes cohérentes. |
| IAM | Pas de droits trop larges, pas de wildcard inutile. |
| Database | Pas de remplacement, suppression ou perte backup. |
| Compute | Capacité, health checks, autoscaling, image/version. |
| Secrets | Aucune valeur sensible affichée. |
| Cost | Pas 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 mergeFenê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 ?
| Changement | Fenêtre recommandée ? | Pourquoi |
|---|---|---|
| Tags ou dashboard | Non en général. | Impact faible. |
| Security group interne | Selon criticité. | Peut couper flux applicatifs. |
| Load balancer / DNS | Oui. | Impact trafic utilisateur. |
| IAM production | Oui. | Peut bloquer application ou pipeline. |
| Database | Oui, obligatoire si risque. | Données, downtime, performance. |
| Réseau VPC / routes | Oui. | 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ésultatCommunication 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.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
- protectedapply doit être manuel et protégé en production, sauf organisation très mature avec policy-as-code robuste.Avant de lancer Apply
| Contrôle | Validation |
|---|---|
| Branche | La branche autorisée est utilisée. |
| Environnement | Production/staging/dev clairement affiché. |
| State | Backend distant et locking actif. |
| Plan | Plan relu, archivé, non obsolète. |
| Credentials | Rôle CI/CD limité et prévu. |
| Monitoring | Dashboards ouverts. |
| Rollback | Procé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.
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
| Zone | Contrôle | Signal attendu |
|---|---|---|
| Cloud | Ressources créées/modifiées visibles. | État healthy / active. |
| Application | Healthcheck HTTP. | 200 OK ou statut attendu. |
| Logs | Erreurs 5xx, exceptions, timeouts. | Pas d’anomalie nouvelle. |
| Metrics | CPU, RAM, latence, saturation, erreurs. | Stable ou attendu. |
| Database | Connexions, locks, réplication, espace disque. | Pas de dégradation. |
| Alerting | Alertes critiques nouvelles. | Aucune alerte inattendue. |
| Business | Login, 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.logDiagramme 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 / rollbackPost-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"'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
| Changement | Rollback typique | Attention |
|---|---|---|
| Security group | Restaurer règle précédente. | Ne pas rouvrir trop large. |
| DNS | Revenir à l’ancien record. | TTL et propagation. |
| Load balancer | Restaurer listener/target group précédent. | Health checks. |
| IAM | Restaurer policy précédente. | Propagation et permissions. |
| Database | Mitigation ou restore backup. | Risque data élevé. |
| State | Restaurer 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 tfplanRunbook 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
│
▼
PostmortemMitigation d’urgence
| Cas | Mitigation possible |
|---|---|
| API inaccessible | Restaurer ancienne listener rule ou target group. |
| DB inaccessible | Restaurer règle security group précédente. |
| DNS incorrect | Revenir ancien record, réduire TTL si possible. |
| IAM bloque application | Restaurer permission minimale nécessaire. |
Cas concrets de production
Cas 1 : changement security group DB
| Objectif | Autoriser un nouveau service applicatif à joindre PostgreSQL. |
| Risque | Bloquer l’ancien service ou ouvrir DB trop largement. |
| Plan à relire | Ingress DB, source security group, port exact. |
| Vérification | Connexion DB depuis nouveau service + logs erreurs DB. |
| Rollback | Restaurer règle précédente. |
Cas 2 : ajout autoscaling
| Objectif | Adapter capacité au trafic. |
| Risque | Scale trop agressif, coût, instabilité. |
| Plan à relire | Min/max capacity, métriques, cooldown. |
| Vérification | Capacité, CPU, latence, nombre d’instances/tâches. |
| Rollback | Revenir min/max précédents ou désactiver policy. |
Cas 3 : changement DNS
| Objectif | Pointer un domaine vers un nouveau load balancer. |
| Risque | Trafic vers mauvaise cible, propagation lente. |
| Plan à relire | Record, zone, TTL, cible. |
| Vérification | dig, curl, logs load balancer. |
| Rollback | Restaurer ancien record, tenir compte TTL. |
Cas 4 : modification RDS
| Objectif | Augmenter stockage ou classe instance. |
| Risque | Downtime, performance, coût, maintenance window. |
| Plan à relire | Replace interdit, backup, multi-AZ, apply immediately. |
| Vérification | Connexions, latence DB, espace disque, locks. |
| Rollback | Souvent non trivial : mitigation ou nouvelle modification. |
Anti-patterns du déploiement infrastructure
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| Apply local en production | Pas de traçabilité complète, variables locales divergentes. | Apply via CI/CD protégé. |
| Plan non relu | Destroy/replace non détecté. | Review obligatoire du plan. |
| Changement énorme | Impossible à relire et rollback complexe. | Petits changements isolés. |
| Apply juste avant départ | Personne disponible en cas d’incident. | Fenêtre avec surveillance. |
| Pas de monitoring | Incident 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 concurrent | State 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éModèle professionnel
CI/CD protégé
│
├── change request
├── plan archivé
├── review
├── approval
├── apply manuel
├── post-checks
└── documentationChecklist de déploiement infrastructure
Avant merge
| Point | Validation attendue |
|---|---|
| Ticket / change request | Objectif, impact, risque, rollback décrits. |
| Terraform fmt | Format OK. |
| Terraform validate | Validation OK. |
| Scan sécurité | Pas de risque bloquant non traité. |
| Plan | Plan généré, lisible et archivé. |
| Review | Plan relu par une personne compétente. |
| Destroy / replace | Absents ou explicitement justifiés. |
| Rollback | Procédure écrite ou mitigation claire. |
Avant apply production
| Question | Ré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
| Cloud | Ressources healthy. |
| App | Healthchecks OK. |
| Logs | Pas de nouvelles erreurs critiques. |
| Metrics | Latence, erreurs, CPU/RAM stables. |
| Alerting | Aucune alerte inattendue. |
| Documentation | Changement clôturé avec résultat. |
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-onlyL’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.
Les questions à couvrir
| Question | Signal 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 responseObservabilité utile vs bruit
| Signal utile | Bruit 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. |
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
| Pilier | Usage | Exemple |
|---|---|---|
| Events | Marquer les changements importants. | Déploiement, Terraform apply, scaling event. |
| Audit logs | Tracer les actions sensibles. | Qui a modifié IAM, security group, secret. |
| SLO / SLI | Mesurer la fiabilité du point de vue utilisateur. | 99.9% de requêtes API réussies sous 300 ms. |
| Dashboards | Voir rapidement l’état de production. | Golden signals, infra, DB, CI/CD. |
| Alerting | Notifier 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 DBLogs : 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
| Source | Exemples | Utilité |
|---|---|---|
| Application | Exceptions, erreurs métier, login, jobs. | Comprendre le comportement applicatif. |
| Nginx / proxy | Access logs, status code, latence, IP. | Analyser trafic et erreurs HTTP. |
| System | systemd, kernel, auth, disk. | Diagnostiquer serveur Linux. |
| Database | Slow queries, locks, connexions, erreurs. | Identifier saturation ou requêtes lentes. |
| CI/CD | Pipeline failed, Terraform apply, déploiements. | Relier incident à changement récent. |
| Cloud audit | IAM 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
| Pratique | Pourquoi |
|---|---|
| Logs structurés JSON | Recherches et agrégations beaucoup plus fiables. |
| Request ID / Trace ID | Corréler logs entre services. |
| Niveau clair | debug, info, warning, error, critical. |
| Pas de secrets | Éviter fuite token, mot de passe, cookie, Authorization header. |
| Rétention adaptée | Coût, conformité, capacité d’investigation. |
| Indexation utile | Service, 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.logMé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
| Signal | Signification | Exemples |
|---|---|---|
| Latency | Temps de réponse ressenti. | p50, p95, p99 par endpoint. |
| Traffic | Volume de demandes. | RPS, jobs/min, messages queue. |
| Errors | Taux d’échec. | 5xx, exceptions, failed jobs. |
| Saturation | Ressources proches de la limite. | CPU, RAM, disque, connexions DB. |
Métriques système
| CPU | Usage, load average, steal time. |
| RAM | Utilisation, swap, OOM kills. |
| Disque | Usage %, I/O wait, inode usage. |
| Réseau | Débit, erreurs, connexions, drops. |
Métriques applicatives et DB
| Domaine | Métriques clés |
|---|---|
| HTTP | RPS, 2xx/4xx/5xx, latence p95, taille réponse. |
| Application | Exceptions, temps traitement, cache hit ratio. |
| Workers | Queue length, job duration, failed jobs, retries. |
| PostgreSQL/MySQL | Connexions, slow queries, locks, replication lag. |
| Redis | Memory, evictions, hit ratio, connected clients. |
| CI/CD | Pipeline 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, mitigationTraces 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 msCe qu’une trace révèle
| Signal | Interprétation |
|---|---|
| Span très long | Service ou requête DB lente. |
| Erreur sur span externe | Dépendance tierce en échec. |
| Beaucoup de spans DB | Possible problème N+1 queries. |
| Trace sans request ID | Corrélation logs difficile. |
Outils de tracing
| Outil | Usage |
|---|---|
| OpenTelemetry | Standard d’instrumentation traces/metrics/logs. |
| Jaeger | Tracing distribué open source. |
| Grafana Tempo | Stockage traces intégré écosystème Grafana. |
| Datadog APM | APM SaaS complet avec traces, metrics, logs. |
| New Relic | APM, 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 completAlertes : 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
| Domaine | Alerte typique | Action attendue |
|---|---|---|
| HTTP | 5xx > 2% pendant 5 min. | Vérifier app, déploiement récent, logs. |
| Latence | p95 > 1s pendant 10 min. | Analyser DB, cache, dépendances. |
| Disque | Disk usage > 85%. | Nettoyer, augmenter volume, vérifier logs. |
| Database | Connexions > 80% max. | Analyser pooling, requêtes, saturation. |
| Queue | Backlog augmente pendant 15 min. | Vérifier workers, erreurs, scaling. |
| CI/CD | Pipeline prod failed. | Vérifier état partiel, state lock, rollback. |
Niveaux d’alerte
| Niveau | Impact | Canal |
|---|---|---|
| Info | Événement notable, pas d’action immédiate. | Dashboard, log, notification faible. |
| Warning | Risque ou tendance à surveiller. | Slack/Email équipe. |
| Critical | Impact 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 claireExemple 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
| Domaine | Indicateurs | Pourquoi |
|---|---|---|
| Vue service | Disponibilité, RPS, 5xx, p95/p99. | État utilisateur. |
| Application | Exceptions, endpoints lents, jobs failed. | Diagnostic métier. |
| Infrastructure | CPU, RAM, disque, réseau. | Saturation ressources. |
| Database | Connexions, locks, slow queries, replication lag. | Cause fréquente de lenteur. |
| Cache / queue | Hit ratio, evictions, backlog, retries. | Performance et async. |
| Déploiements | Dernier 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 / AuditBon design de dashboard
| Bonne pratique | Raison |
|---|---|
| Vue haut niveau en premier | Comprendre la santé générale en 30 secondes. |
| Percentiles | Montrer les vrais problèmes de latence. |
| Labels env/service | Filtrer prod/staging/dev et composants. |
| Annotations deploy | Corré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 alertsObservabilité en production : cas concrets
Cas 1 : hausse des erreurs 5xx après déploiement
| Signal | 5xx passe de 0.1% à 4% après release. |
| Dashboard | Erreur HTTP, endpoint impacté, version déployée. |
| Logs | Exceptions sur route /api/orders. |
| Trace | Erreur lors appel payment provider. |
| Action | Rollback applicatif ou feature flag. |
Cas 2 : saturation disque
| Signal | Disque > 90%, logs en croissance rapide. |
| Cause possible | Logs debug activés, rotation absente, batch bavard. |
| Action immédiate | Nettoyage contrôlé, rotation logs, extension volume. |
| Prévention | Alerting 75/85/95%, logrotate, rétention. |
Cas 3 : base de données lente
| Signal | Latence p95 augmente, CPU DB élevé, slow queries. |
| Logs | Requêtes lentes, locks, timeout. |
| Métriques | Connexions saturées, I/O wait, cache hit ratio faible. |
| Action | Identifier requête, index, pooling, rollback si régression. |
Cas 4 : pipeline Terraform échoué
| Signal | Job apply prod failed. |
| Risque | Changement partiellement appliqué. |
| Vérification | terraform plan, state lock, ressources cloud modifiées. |
| Action | Ne pas relancer aveuglément, analyser état partiel. |
Outils d’observabilité
Stack open source fréquente
| Outil | Rôle |
|---|---|
| Prometheus | Collecte et stockage de métriques. |
| Grafana | Dashboards et visualisation. |
| Alertmanager | Routage et gestion des alertes. |
| Loki | Logs orientés labels, intégré Grafana. |
| ELK / OpenSearch | Recherche et analyse de logs. |
| Jaeger / Tempo | Tracing distribué. |
| OpenTelemetry | Standard d’instrumentation et collecte. |
Stack SaaS fréquente
| Datadog | Métriques, logs, traces, APM, SLO. |
| New Relic | APM, infrastructure, logs, monitoring. |
| Dynatrace | APM entreprise, auto-discovery, IA ops. |
| CloudWatch | Monitoring natif AWS. |
| Azure Monitor | Monitoring natif Azure. |
| Google Cloud Monitoring | Monitoring 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 responseChoix rapide
| Besoin | Option adaptée |
|---|---|
| Petit projet cloud AWS | CloudWatch + dashboards simples. |
| Stack open source | Prometheus + Grafana + Loki. |
| Logs puissants | ELK / OpenSearch. |
| Microservices | OpenTelemetry + tracing. |
| Entreprise multi-stack | Datadog / New Relic / Dynatrace. |
Anti-patterns observabilité
| Anti-pattern | Pourquoi c’est dangereux | Alternative professionnelle |
|---|---|---|
| Pas d’alertes avant prod | Les utilisateurs détectent les incidents avant l’équipe. | Alertes minimales avant mise en ligne. |
| Trop d’alertes | Fatigue, alertes ignorées. | Alertes orientées impact et action. |
| Logs non structurés | Recherche lente et corrélation difficile. | JSON logs avec request_id/trace_id. |
| Pas de corrélation deploy | Impossible de relier incident à changement récent. | Annotations de déploiement et events. |
| Dashboard trop dense | Illisible en incident. | Vue synthétique + dashboards spécialisés. |
| Seuils arbitraires | Faux positifs ou faux négatifs. | Seuils basés sur baseline et SLO. |
| Logger des secrets | Fuite de tokens ou données sensibles. | Redaction, filtres, interdiction headers sensibles. |
| Pas de runbook | L’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 runbookModè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ésChecklist observabilité production
Checklist minimale avant go-live
| Point | Validation attendue |
|---|---|
| Health check | Endpoint fiable pour vérifier le service. |
| Logs centralisés | Application, proxy, workers, erreurs. |
| Métriques HTTP | RPS, 5xx, latence p95/p99. |
| Métriques système | CPU, RAM, disque, réseau. |
| Métriques DB | Connexions, slow queries, locks, stockage. |
| Alertes critiques | Service down, 5xx, disque, DB saturation. |
| Dashboard global | Vue production lisible rapidement. |
| Runbooks | Actions associées aux alertes principales. |
Checklist après déploiement
| Question | Ré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. |
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 failedUn 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.
Les objectifs d’une gestion d’incident professionnelle
| Objectif | Résultat attendu |
|---|---|
| Qualifier | Comprendre rapidement l’impact, la gravité et le périmètre. |
| Stabiliser | Éviter que l’incident empire ou se propage. |
| Mitiger | Restaurer partiellement ou totalement le service. |
| Communiquer | Informer clairement les parties prenantes sans spéculation. |
| Restaurer | Valider le retour au nominal par des signaux mesurables. |
| Analyser | Identifier 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éventivesSignaux typiques d’incident
| Signal | Interprétation possible |
|---|---|
| HTTP 5xx élevé | Erreur applicative, DB, dépendance externe, config. |
| Latence p95/p99 élevée | DB lente, saturation CPU, queue, API externe lente. |
| Healthcheck KO | Service indisponible ou dépendance critique KO. |
| Queue backlog | Workers bloqués, volume trop élevé, erreur répétée. |
| State lock Terraform | Pipeline actif, lock orphelin ou apply bloqué. |
| Disque plein | Logs excessifs, backup bloqué, rotation absente. |
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é
| Niveau | Impact | Exemples | Réponse |
|---|---|---|---|
| SEV-1 | Service critique indisponible ou perte de données. | Site down, API principale KO, DB prod inaccessible. | Mobilisation immédiate, canal incident, updates fréquents. |
| SEV-2 | Dégradation forte mais contournement possible. | Latence élevée, fonctionnalité clé dégradée. | Réponse rapide, responsable incident nommé. |
| SEV-3 | Impact partiel ou non critique. | Batch retardé, dashboard interne KO. | Traitement prioritaire mais sans mobilisation totale. |
| SEV-4 | Faible impact ou anomalie préventive. | Alerte capacité, warning sécurité, bug mineur. | Suivi normal, planification correction. |
Critères de qualification
| Critère | Question |
|---|---|
| Utilisateurs | Combien d’utilisateurs sont touchés ? Tous, certains, un segment ? |
| Fonction métier | Login, paiement, API, backoffice, batch, reporting ? |
| Durée | Depuis quand le problème existe-t-il ? |
| Dégradation | Down total, lent, intermittent, erreurs partielles ? |
| Données | Risque 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 standardRô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ôle | Responsabilité | Erreur à éviter |
|---|---|---|
| Incident Commander | Coordonne, décide, priorise, garde la vision globale. | Tout faire soi-même. |
| Tech Lead Incident | Pilote l’analyse technique et les hypothèses. | Changer de piste toutes les 2 minutes. |
| Ops / DevOps | Vérifie infra, logs, métriques, rollback, scaling. | Appliquer des corrections sans validation. |
| App Engineer | Analyse code, erreurs applicatives, release récente. | Ignorer les signaux infra. |
| Communications Lead | Informe équipes, métier, clients si nécessaire. | Communiquer des hypothèses comme des faits. |
| Scribe | Note 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ésultatRègles de canal
| Un responsable incident clair | Évite les décisions contradictoires. |
| Pas de débat long en crise | On privilégie actions réversibles et vérifiables. |
| Chaque action annoncée | Commande, rollback, restart, scaling, changement config. |
| Chaque action vérifiée | On mesure le résultat, pas d’impression vague. |
| Chronologie tenue | Indispensable pour RCA et post-mortem. |
Méthode en 6 étapes
- Qualifier : identifier qui est impacté, quel service est touché, depuis quand, avec quelle gravité.
- Stabiliser : stopper les déploiements, éviter les changements concurrents, empêcher l’incident de s’étendre.
- Mitiger : rollback, restart contrôlé, scale, bypass, désactivation feature flag, correction minimale.
- Communiquer : envoyer des messages courts, factuels, réguliers, sans spéculation excessive.
- Restaurer : vérifier retour au nominal par métriques, logs, health checks, parcours métier.
- Analyser : cause racine, facteurs contributifs, actions préventives, suivi post-mortem.
Actions rapides possibles
| Action | Quand l’utiliser | Risque |
|---|---|---|
| Rollback app | Incident après release applicative. | Perte de correction récente. |
| Rollback Terraform | Incident après changement infra. | Plan de rollback à relire. |
| Feature flag off | Fonctionnalité nouvelle problématique. | Fonction désactivée temporairement. |
| Scale up | Saturation capacité. | Coût, masque cause racine. |
| Bypass dépendance | API 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éventionCommandes 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
topChronologie 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
| Temps | Action / observation | But |
|---|---|---|
| T+0 | Alerte 5xx élevée sur API production. | Détection. |
| T+3 | Dashboard confirme 5xx sur /api/orders. | Confirmer impact. |
| T+5 | Canal incident créé, Incident Commander nommé. | Coordination. |
| T+8 | Dernier déploiement app identifié à T-10. | Hypothèse principale. |
| T+12 | Rollback release applicative lancé. | Mitigation. |
| T+18 | 5xx descend progressivement. | Vérifier efficacité. |
| T+25 | Health checks et parcours métier OK. | Retour nominal. |
| T+45 | Surveillance prolongée, aucun nouveau pic. | Stabilisation. |
| T+90 | Post-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étection | Quand l’incident a été vu. |
| Heure de début réel | Quand les métriques montrent le début. |
| Actions prises | Rollback, restart, scale, hotfix, changement config. |
| Décisions | Pourquoi une piste a été choisie. |
| Résultats | Effet mesuré après action. |
| Retour nominal | Quand les signaux sont redevenus stables. |
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
| Incident | Mitigation rapide | Vérification |
|---|---|---|
| Release applicative cassée | Rollback image/version précédente. | 5xx, healthcheck, parcours critique. |
| Security group trop restrictif | Restaurer règle précédente ou correctif minimal. | Connectivité service → DB. |
| Saturation CPU | Scale up/out temporaire. | CPU, latence, erreurs. |
| DB connexions saturées | Réduire workers, ajuster pool, redémarrage contrôlé. | Connexions, locks, erreurs DB. |
| API externe lente | Timeout, circuit breaker, mode dégradé. | Latence et erreurs endpoint. |
| Disque plein | Nettoyage logs/cache, extension volume. | df -h, logs, service OK. |
| DNS incorrect | Restaurer 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èseActions à éviter en urgence
| Faire plusieurs changements simultanés | Impossible de savoir ce qui a aidé ou empiré. |
| Modifier la DB sans backup | Risque de corruption ou perte. |
| Force-unlock Terraform sans preuve | Peut casser un apply actif. |
| Ouvrir largement le réseau | Crée une dette sécurité immédiate. |
| Redémarrer tous les services au hasard | Peut aggraver la panne ou perdre indices. |
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ègle | Pourquoi |
|---|---|
| Être factuel | Éviter spéculation et contradictions. |
| Dire ce qui est impacté | Service, fonctionnalité, région, clients. |
| Dire ce qui est fait | Mitigation, rollback, investigation. |
| Donner un prochain update | Réduit les sollicitations. |
| Ne pas désigner de coupable | Garder une culture blameless. |
| Ne pas promettre sans certitude | Pré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é.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
| Niveau | Exemple |
|---|---|
| Symptôme | API retourne 500. |
| Cause technique immédiate | Timeout PostgreSQL sur endpoint commandes. |
| Cause technique profonde | Nouvelle requête sans index déclenche full scan. |
| Cause process | Pas de test de volume ni alerte slow query en staging. |
| Prévention | Ajouter 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
| Famille | Questions |
|---|---|
| Technique | Code, infra, DB, réseau, provider, capacité ? |
| Process | Review, tests, approvals, runbooks suffisants ? |
| Observabilité | Alerte trop tardive ? Dashboard insuffisant ? |
| Organisation | Ownership clair ? Escalade rapide ? |
| Documentation | Rollback 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érifiablesPost-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 - DateQualité des actions post-mortem
| Mauvaise action | Bonne 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.
Exemples d’incidents production
Tableau de cas fréquents
| Incident | Mitigation rapide | Pré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 SGCas 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 stockageChecklist gestion d’incident production
Checklist pendant incident
| Point | Validation |
|---|---|
| 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 choisie | Action réversible ou contrôlée. |
| Communication envoyée | Message court, factuel, prochain update. |
| Chronologie tenue | Actions 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
| Point | Résultat attendu |
|---|---|
| Post-mortem créé | Document clair, partagé. |
| Timeline complète | Détection, mitigation, retour nominal. |
| Impact mesuré | Durée, utilisateurs, services, données. |
| Cause racine identifiée | Technique + process + observabilité. |
| Actions assignées | Owner + date + résultat vérifiable. |
| Runbook mis à jour | Procédure améliorée. |
| Alerte ajustée | Détection plus rapide ou moins de bruit. |
| Prévention suivie | Actions fermées, pas oublié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.