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).
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 planmontre exactement ce qui va changer — comme un diff — avant tout déploiement. En CI/CD, ce plan est soumis à approbation humaine avantapply.
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ôlepostgresql, rôlemonitoring). 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é

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 principal | Provisionnement (créer/détruire des ressources) | Configuration (installer, configurer, déployer) |
| Cible | APIs cloud (Azure, AWS, GCP, DNS, FW...) | Serveurs existants (OS, packages, fichiers) |
| Approche | Déclarative (HCL) | Déclarative + procédurale (YAML) |
| État | State file (gestion explicite) | Stateless (état lu sur le serveur à chaque run) |
| Idempotence | Oui (natif) | Oui (si modules bien écrits) |
| Courbe apprentissage | Moyenne (HCL, state, providers) | Faible (YAML lisible) |
| Cas d'usage PME | Créer VMs, VNets, DBs, LBs dans le cloud | Configurer 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 →Téléchargez ce guide IaC en PDF.
⬇ Télécharger le guide (PDF)