Infrastructure as Code : Terraform, Ansible, GitOps pour PME

Fini le clic-ops. Terraform pour le cloud, Ansible pour les serveurs, GitOps pour le pipeline — guide IaC terrain pour PME avec cas concret BOTUM (4h → 11 min).

Infrastructure as Code : Terraform, Ansible, GitOps pour PME

Votre infra cloud a été construite à la main. Un clic ici, un portail Azure là, une VM créée en console AWS un vendredi soir sous pression. Six mois plus tard, personne ne sait vraiment ce qui tourne, pourquoi, ni comment le reproduire en cas de sinistre. C'est le "clic-ops" — et c'est la première source de dette technique dans les organisations IT que nous accompagnons chez BOTUM.

L'Infrastructure as Code (IaC) est la réponse structurelle à ce problème. Pas une tendance, pas un luxe réservé aux grandes entreprises — un prérequis pour toute PME qui veut maîtriser son infra cloud en 2025.

L'IaC en vrai : déclarer l'état désiré, pas les étapes

La distinction fondamentale de l'IaC est philosophique avant d'être technique : vous déclarez ce que vous voulez, pas comment y arriver. Vous écrivez "je veux une VM de type Standard_B2s dans East US avec un disque de 128 Go et ce groupe de sécurité" — et l'outil se charge de créer, modifier ou supprimer les ressources pour que la réalité corresponde à cette déclaration.

C'est l'approche déclarative, opposée à l'approche impérative (scripts de création en séquence). La déclarative est idempotente : appliquer deux fois le même code donne le même résultat, sans effets de bord.

Concrètement, votre infra devient du code versionné dans Git : historique complet, revues de code, rollback instantané, audit trail. Tout ce que vous faites déjà pour votre code applicatif, vous le faites maintenant pour votre infrastructure.

Terraform : provisionnement cloud

Terraform (HashiCorp, open-source) est le standard de facto pour provisionner des ressources cloud : VMs, VNets, bases de données, load balancers, DNS, IAM. Il parle à l'API de 3000+ providers (Azure, AWS, GCP, Cloudflare, GitHub...).

Un exemple concret — créer un groupe de ressources Azure et une VM :

# main.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.90"
    }
  }
  backend "azurerm" {
    resource_group_name  = "rg-tfstate"
    storage_account_name = "botumtfstate"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}

resource "azurerm_resource_group" "main" {
  name     = "rg-botum-prod"
  location = "canadacentral"
}

resource "azurerm_linux_virtual_machine" "app" {
  name                = "vm-app-prod-01"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  size                = "Standard_B2s"
  admin_username      = "azureuser"

  network_interface_ids = [azurerm_network_interface.app.id]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
    disk_size_gb         = 128
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

Points clés :

  • State file : Terraform maintient un état de ce qu'il a créé (terraform.tfstate). Ce fichier doit être stocké en backend remote (Azure Blob, S3) — jamais en local, jamais dans Git. C'est la principale source de catastrophes chez les débutants.
  • Modules : Regroupez les ressources logiques en modules réutilisables (module "vm" { source = "./modules/vm" }). Un module pour les VMs, un pour la base de données, un pour le réseau. Réutilisable entre projets.
  • Plan avant Apply : terraform plan montre exactement ce qui va changer — comme un diff — avant tout déploiement. En CI/CD, ce plan est soumis à approbation humaine avant apply.

Ansible : configuration et déploiement

Terraform crée l'infra. Ansible la configure. Une fois votre VM Azure créée, Ansible installe Nginx, copie les configs, crée les comptes utilisateurs, configure les certificats TLS — de façon idempotente.

Un playbook Ansible basique pour configurer un serveur web :

# playbooks/web-server.yml
---
- name: Configure web server
  hosts: web_servers
  become: yes
  vars:
    app_port: 8080
    app_user: botum

  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: yes

    - name: Deploy nginx config
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/botum
        mode: '0644'
      notify: Reload nginx

    - name: Create app user
      ansible.builtin.user:
        name: "{{ app_user }}"
        system: yes
        shell: /usr/sbin/nologin

  handlers:
    - name: Reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded

Ce qui rend Ansible puissant pour les PME :

  • Idempotence : relancer le même playbook 10 fois donne le même résultat. Pas d'effet de bord, pas de "déjà installé" qui plante.
  • Agentless : Ansible se connecte via SSH — aucun agent à installer sur les serveurs cibles.
  • Rôles : structurez vos playbooks en rôles réutilisables (rôle nginx, rôle postgresql, rôle monitoring). Ansible Galaxy fournit des centaines de rôles communautaires testés.
  • Inventory dynamique : Ansible peut interroger Azure/AWS pour découvrir automatiquement les VMs à configurer — pas de liste statique à maintenir.

GitOps : Git comme source de vérité

Pipeline GitOps IaC — 4 étapes

GitOps est le principe qui unifie tout : Git est la seule source de vérité pour l'état désiré de votre infra. Toute modification passe par une Pull Request — ce qui en fait automatiquement un ticket de change auditables, avec discussion, approbation, et historique.

Le flux complet avec GitHub Actions :

# .github/workflows/terraform.yml
name: Terraform CI/CD

on:
  pull_request:
    paths: ['terraform/**']
  push:
    branches: [main]
    paths: ['terraform/**']

jobs:
  plan:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "1.7.0"
      - name: Terraform Init
        run: terraform -chdir=terraform init
        env:
          ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
          ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
          ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
          ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
      - name: Terraform Plan
        run: terraform -chdir=terraform plan -out=tfplan
      - name: Comment PR
        uses: actions/github-script@v7
        # Poste le plan en commentaire de la PR pour revue

  apply:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    environment: production  # Approbation manuelle requise
    steps:
      - uses: actions/checkout@v4
      - name: Terraform Apply
        run: terraform -chdir=terraform apply -auto-approve

Le résultat : chaque modification d'infra est une PR. Le plan Terraform est posté en commentaire automatiquement. Un second ingénieur approuve. Le merge déclenche l'apply automatique. L'historique Git montre exactement qui a changé quoi, quand, et pourquoi (message de commit).

Terraform vs Ansible : qui fait quoi

Critère Terraform Ansible
Rôle principalProvisionnement (créer/détruire des ressources)Configuration (installer, configurer, déployer)
CibleAPIs cloud (Azure, AWS, GCP, DNS, FW...)Serveurs existants (OS, packages, fichiers)
ApprocheDéclarative (HCL)Déclarative + procédurale (YAML)
ÉtatState file (gestion explicite)Stateless (état lu sur le serveur à chaque run)
IdempotenceOui (natif)Oui (si modules bien écrits)
Courbe apprentissageMoyenne (HCL, state, providers)Faible (YAML lisible)
Cas d'usage PMECréer VMs, VNets, DBs, LBs dans le cloudConfigurer Nginx, Postgres, déployer apps

Règle simple : Terraform pour tout ce qui est dans le portail cloud. Ansible pour tout ce qui se fait en SSH sur un serveur.

Pour les PME : commencer simple

La tentation est d'aller trop vite — Terragrunt, Pulumi, ArgoCD, tout d'un coup. Mauvaise idée. Voici la progression recommandée pour une PME de 10-200 employés :

Étape 1 — Un repo, une structure simple :

infra-repo/
├── terraform/
│   ├── environments/
│   │   ├── dev/
│   │   ├── staging/
│   │   └── prod/
│   └── modules/
│       ├── vm/
│       └── network/
├── ansible/
│   ├── inventory/
│   ├── playbooks/
│   └── roles/
└── .github/
    └── workflows/
        ├── terraform.yml
        └── ansible.yml

Étape 2 — Commencer par l'environnement de dev. Migrez d'abord dev en IaC. Apprenez, faites des erreurs sans impact prod. Affinez les modules. Mesurez le temps gagné.

Étape 3 — Étendre à staging puis prod. Même code, variables différentes. La valeur de l'IaC explose quand vous pouvez créer staging en 10 min depuis les modules prod éprouvés.

Étape 4 — Pipeline GitHub Actions basique. Plan automatique sur les PRs. Apply manuel (approbation) sur main. Pas besoin de plus pour commencer.

Les pièges qui font mal

❌ State file en local ou dans Git

Le terraform.tfstate contient des secrets en clair (mots de passe de base de données, clés API). Le commit dans Git = fuite de credentials. La solution : backend remote chiffré (Azure Blob avec CMK, S3 avec SSE, Terraform Cloud). Sans exception.

❌ Secrets en dur dans les fichiers HCL ou YAML

Le password = "MonMotDePasse123" dans un fichier Terraform versionné, c'est la bêtise classique. Utilisez des variables d'environnement injectées par le CI/CD depuis un gestionnaire de secrets (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault). En Ansible : ansible-vault encrypt pour les fichiers sensibles.

❌ Versions Terraform non épinglées

Sans required_version = "~> 1.7.0" et version = "~> 3.90" sur les providers, une mise à jour automatique peut casser votre pipeline du jour au lendemain. Toujours épingler les versions. Toujours tester les upgrades de providers en dev d'abord.

❌ Pas de séparation des environnements

Un seul state file pour dev/staging/prod = catastrophe. Un terraform destroy accidentel en "dev" peut tuer la prod si les workspaces ne sont pas correctement isolés. Utilisez des répertoires séparés ou des workspaces Terraform avec backends distincts.

Cas concret BOTUM : 3 environnements, 10 min de déploiement

Client SaaS B2B, 35 employés, stack Azure. Situation initiale : infra créée à la main au fil des années. Aucune documentation à jour. Recrutement d'un DevOps bloqué 3 semaines à "comprendre ce qui tourne". Reprise après incident : 4h minimum pour recréer un environnement staging.

Migration IaC réalisée avec BOTUM — 6 semaines :

  • Semaines 1-2 : audit de l'infra existante, import des ressources dans Terraform (terraform import), création des modules VM/réseau/DB
  • Semaines 3-4 : structuration Ansible (rôles nginx, node.js, postgresql, monitoring), tests en dev
  • Semaines 5-6 : pipeline GitHub Actions (plan auto sur PR, apply sur merge avec approbation), migration staging puis prod

Stack déployée :

  • Terraform 1.7 + AzureRM provider 3.x → provisionnement AKS, Azure PostgreSQL Flexible, Key Vault, VNet
  • Ansible 2.16 → configuration des workers, déploiement des apps Node.js, rotation des certificats Let's Encrypt
  • GitHub Actions → pipeline complet, secrets dans Azure Key Vault via federated identity (OIDC, zéro secret stocké dans GitHub)
  • State file dans Azure Blob Storage avec chiffrement CMK + lock d'état (anti-concurrent)

Résultats :

  • Création d'un environnement staging complet : 4h → 11 minutes
  • Onboarding d'un nouveau DevOps : 3 semaines → 2 jours (lire le repo = comprendre l'infra)
  • Incidents liés à une mauvaise configuration manuelle : 0 depuis le déploiement IaC
  • Audit de conformité (revue de sécurité client Enterprise) : toutes les modifications tracées dans Git

La transformation clé : l'infra est passée de "connaissance tribale" d'une personne à un actif d'entreprise documenté, versionné, testable.

Conclusion : l'IaC n'est pas une option

L'Infrastructure as Code n'est plus une pratique "avancée" réservée aux équipes de 50 ingénieurs. C'est le minimum pour une PME qui veut :

  • Reproductibilité : recréer un environnement en minutes, pas en jours
  • Traçabilité : savoir exactement qui a changé quoi dans votre infra
  • Résilience : rollback instantané, disaster recovery scriptable
  • Conformité : audit trail pour SOC2, ISO 27001, PIPEDA

Le point d'entrée est simple : commencez par un seul repo, Terraform pour le cloud, Ansible pour les VMs, GitHub Actions pour le pipeline. Vous aurez 80% de la valeur avec 20% de la complexité.

🚀 Aller plus loin avec BOTUM

Mettre en place l'IaC dans votre organisation ? Les équipes BOTUM vous accompagnent de A à Z.

Discuter de votre projet →
📥 Guide PDF complet

Téléchargez ce guide IaC en PDF.

⬇ Télécharger le guide (PDF)
📚 Série Cloud Journey 📋 Voir la série complète →