← Retour aux tutoriels

Bonnes pratiques DevOps : CI/CD, IaC et observabilité

devopsci-cdkubernetesterraformdevsecopsobservabilitesredocker

Bonnes pratiques DevOps : CI/CD, IaC et observabilité

Ce tutoriel présente une approche complète et pragmatique des bonnes pratiques DevOps autour de trois piliers : CI/CD (intégration et déploiement continus), IaC (Infrastructure as Code) et observabilité (logs, métriques, traces). L’objectif est de comprendre pourquoi ces pratiques existent, comment les mettre en place, et quels pièges éviter, avec des commandes réelles et des exemples reproductibles.


1) Prérequis et cadre de référence

Prérequis techniques

Vérification rapide :

git --version
docker --version
terraform version
kubectl version --client

Principes DevOps à garder en tête


2) CI/CD : construire une chaîne fiable et rapide

2.1 CI vs CD : définitions utiles

Dans la pratique, une bonne pipeline CI/CD doit :

  1. Valider le code (lint, tests, sécurité)
  2. Construire un artefact immuable (image Docker, package)
  3. Publier l’artefact (registry)
  4. Déployer via un mécanisme reproductible (IaC + GitOps idéalement)
  5. Vérifier (smoke tests, health checks, SLO)
  6. Permettre rollback/rollforward

2.2 Stratégie Git : branches, PR/MR, et qualité

Recommandations :

Exemples de conventions de commits (inspirées Conventional Commits) :

Vérifier l’historique :

git log --oneline --decorate --graph --all | head -n 30

2.3 Exemple concret : pipeline CI pour une application Node.js conteneurisée

Arborescence type

.
├── src/
├── test/
├── package.json
├── package-lock.json
├── Dockerfile
└── scripts/
    ├── lint.sh
    └── test.sh

Scripts de qualité (exemples)

scripts/lint.sh :

#!/usr/bin/env bash
set -euo pipefail
npm ci
npm run lint

scripts/test.sh :

#!/usr/bin/env bash
set -euo pipefail
npm ci
npm test

Rendre exécutables :

chmod +x scripts/*.sh

Dockerfile (exemple)

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm test

FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app /app
EXPOSE 3000
CMD ["node", "src/index.js"]

Build local :

docker build -t monapp:dev .
docker run --rm -p 3000:3000 monapp:dev

2.4 Artefacts immuables et versionnement

Bonnes pratiques :

Exemple :

GIT_SHA="$(git rev-parse --short HEAD)"
docker build -t registry.exemple.com/monapp:${GIT_SHA} .
docker push registry.exemple.com/monapp:${GIT_SHA}

2.5 Sécurité dans la CI : SAST, dépendances, secrets

Intégrer des contrôles tôt :

Commandes typiques :

npm audit --audit-level=high

Scan d’image avec Trivy (si installé) :

trivy image --severity HIGH,CRITICAL monapp:dev

Détection de secrets (exemple gitleaks) :

gitleaks detect --source . --no-git

Principe clé : un pipeline qui échoue tôt est un pipeline qui protège.


2.6 Déploiement : stratégies et garde-fous

Stratégies de déploiement

Garde-fous indispensables

Exemple de smoke test HTTP :

curl -fsS http://mon-service.exemple.com/health

3) IaC : Infrastructure as Code fiable, testable et traçable

3.1 Pourquoi l’IaC est incontournable

Sans IaC, l’infrastructure dérive :

Avec IaC :

Deux familles :


3.2 Terraform : structure et bonnes pratiques

Structure recommandée

Exemple :

infra/
├── modules/
│   └── réseau/
└── envs/
    ├── dev/
    └── prod/

Initialiser et planifier

Dans un dossier Terraform :

terraform init
terraform fmt -recursive
terraform validate
terraform plan

Appliquer :

terraform apply

Détruire (à manier avec extrême prudence) :

terraform destroy

3.3 Gestion du state : sécurité et collaboration

Le fichier terraform.tfstate contient souvent :

Bonnes pratiques :

Même sans montrer de configuration spécifique, retenez :


3.4 Variables, secrets et séparation des environnements

Exemple d’exécution avec variables :

terraform plan -var="region=eu-west-1" -var="env=dev"

3.5 Import et dérive (drift)

Si une ressource est modifiée hors Terraform, on observe une dérive.

Détecter :

terraform plan

Importer une ressource existante (exemple générique) :

terraform import module.reseau.aws_vpc.main vpc-1234567890abcdef0

Attention : importer ne génère pas automatiquement le code HCL correct. Il faut ensuite aligner la configuration.


3.6 Tests et qualité IaC

Même l’infra doit être testée :

Exemples :

tflint --recursive
checkov -d infra/

4) Observabilité : logs, métriques, traces (et la réalité opérationnelle)

4.1 Monitoring vs observabilité

Les 3 piliers :

  1. Logs : détails d’événements
  2. Métriques : séries temporelles agrégées
  3. Traces : parcours d’une requête à travers plusieurs services

Un 4e pilier souvent ajouté :


4.2 Logs : structurés, corrélables, exploitables

Bonnes pratiques de logs applicatifs

Exemple de log JSON (ligne unique) :

{"timestamp":"2026-05-08T10:12:33.123Z","level":"info","service":"api","env":"prod","request_id":"abc123","message":"Requête traitée","duration_ms":42}

Centralisation

Objectif : éviter de se connecter sur chaque machine/Pod. Solutions fréquentes :

Exemple de lecture de logs Docker :

docker logs -f --tail=200 <container_id>

4.3 Métriques : SLI/SLO, RED/USE, et alertes utiles

Métriques “techniques” vs “produit”

Méthodes pratiques

SLI/SLO : piloter par objectifs

Exemple de réflexion :


4.4 Traces distribuées : comprendre les latences

Dans une architecture microservices, une requête traverse :

Sans traces, on devine. Avec traces, on voit. Technos typiques :

Concepts clés :


4.5 OpenTelemetry en pratique (exemple conceptuel + commandes)

Même si l’instrumentation dépend du langage, vous pouvez déjà mettre en place un collecteur et exporter des signaux.

Lancer un collecteur OpenTelemetry via Docker (exemple simple) :

docker run --rm -p 4317:4317 -p 4318:4318 otel/opentelemetry-collector:latest

Tester un endpoint OTLP HTTP (selon config, ici purement illustratif) :

curl -v http://localhost:4318/

Dans un vrai setup, vous configurerez le collector pour router vers :


4.6 Alerting : réduire le bruit, augmenter la valeur

Erreurs fréquentes :

Bonnes pratiques :

Exemple de runbook minimal :


5) Mettre ensemble : un flux DevOps cohérent (CI/CD + IaC + Observabilité)

5.1 Chaîne de livraison type

  1. Dev pousse du code
  2. CI :
    • lint + tests
    • scan sécurité
    • build image
    • push registry
  3. CD :
    • mise à jour des manifests (ou release)
    • déploiement automatisé
  4. Observabilité :
    • dashboards (RED/USE)
    • traces activées
    • logs corrélés
  5. Post-déploiement :
    • smoke tests
    • surveillance du budget d’erreur

5.2 Exemple de déploiement Kubernetes (commandes réelles)

Sans entrer dans des manifests complets, voici des commandes typiques d’exploitation.

Voir les ressources :

kubectl get ns
kubectl get pods -n mon-namespace
kubectl get deploy -n mon-namespace
kubectl get svc -n mon-namespace

Décrire un Pod (diagnostic) :

kubectl describe pod -n mon-namespace monapp-xxxxx

Logs d’un Pod :

kubectl logs -n mon-namespace deploy/monapp --tail=200 -f

Rollout status :

kubectl rollout status -n mon-namespace deploy/monapp

Rollback :

kubectl rollout undo -n mon-namespace deploy/monapp

Tester un port-forward pour debug :

kubectl port-forward -n mon-namespace svc/monapp 8080:80
curl -fsS http://localhost:8080/health

5.3 GitOps : déployer via Git comme source de vérité

Principe :

Avantages :


6) Sécurité et conformité : “shift left” sans casser la vélocité

6.1 Contrôles à intégrer

Exemple de génération SBOM avec Syft (si installé) :

syft monapp:dev -o json > sbom.json
jq '.artifacts | length' sbom.json

Signer une image avec cosign (si installé) :

cosign sign registry.exemple.com/monapp:${GIT_SHA}
cosign verify registry.exemple.com/monapp:${GIT_SHA}

6.2 Gestion des secrets

Règles :

Détecter des secrets accidentels avant commit (exemple) :

gitleaks detect --source . --no-git

7) Fiabilité : déploiements sûrs, tests réalistes, et résilience

7.1 Tests : pyramide et couverture utile

Exécuter tests en local (Node) :

npm ci
npm test

7.2 Chaos engineering (à dose raisonnable)

Objectif : valider que le système tolère des pannes réalistes. Commencer petit :

Exemple : supprimer un Pod (il doit être recréé) :

kubectl delete pod -n mon-namespace monapp-xxxxx
kubectl get pods -n mon-namespace -w

8) Anti-patterns fréquents (et comment les éviter)

  1. Pipeline trop lente

    • Solution : paralléliser, cache dépendances, tests ciblés, exécuter SAST en différé si nécessaire (mais bloquer sur critiques).
  2. Déploiements manuels non tracés

    • Solution : GitOps, RBAC strict, audit.
  3. IaC sans modules ni conventions

    • Solution : structure standard, modules réutilisables, lint/policies.
  4. Observabilité “cosmétique” (dashboards sans action)

    • Solution : SLO, alertes actionnables, runbooks, corrélation logs/traces.
  5. Secrets dans les variables CI non maîtrisées

    • Solution : secret manager, rotation, scopes, masquage, revues.

9) Checklist opérationnelle (résumé actionnable)

CI

CD

IaC

Observabilité


10) Conclusion : une approche progressive et durable

Mettre en place CI/CD, IaC et observabilité n’est pas un “projet outil”, c’est une capacité à livrer vite et bien. La progression la plus efficace consiste souvent à :

  1. Stabiliser la CI (tests, qualité, artefacts)
  2. Industrialiser le déploiement (CD) avec rollback et vérifications
  3. Basculer l’infrastructure en IaC (avec state sécurisé et policies)
  4. Investir dans l’observabilité (corrélation logs/métriques/traces)
  5. Mesurer via SLO et améliorer en continu

Si vous voulez, je peux proposer une implémentation complète sur un stack précis (par exemple : GitHub Actions + Terraform + Kubernetes + Prometheus/Grafana + Loki + Tempo + OpenTelemetry), avec une arborescence de repo et des scripts reproductibles.