Leçon 2/3
45 min Observabilité, Automatisation & SRE

Gestion de configuration et IaC

Comparer les approches de gestion de configuration (Ansible) et d'infrastructure as code (Terraform) et leurs garanties d'idempotence.

À retenir

  • Ansible configure des systèmes existants, Terraform provisionne l'infrastructure elle-même.
  • L'idempotence n'est garantie que par des modules déclaratifs, pas par shell/command bruts.
  • Terraform détecte la dérive (drift) via son fichier d'état et le plan avant apply.
  • Le lint et la revue de code sont indispensables avant toute application en production.

Deux familles d'outils, deux objectifs

La gestion de configuration (Ansible, Puppet, Chef) configure l'état interne de machines déjà existantes. L'infrastructure as code (Terraform, Pulumi, OpenTofu) déclare et provisionne les ressources d'infrastructure elles-mêmes (VM, réseaux, bases managées). Les deux se combinent en pratique : Terraform crée la VM, Ansible la configure.

Idempotence : le principe non négociable

Un playbook ou un module doit produire le même état final qu'il soit exécuté une fois ou dix fois. Ansible fournit des modules déclaratifs (package, service, copy, template) conçus pour vérifier l'état courant avant d'agir.

# playbook.yml — exemple idempotent avec Ansible
- name: Configurer le service nginx
  hosts: web
  become: true
  tasks:
    - name: Installer nginx
      ansible.builtin.package:
        name: nginx
        state: present

- name: Déployer la configuration
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: "0644"
      notify: Recharger nginx

- name: S'assurer que le service est actif
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true

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

Point clé

un module comme ansible.builtin.command ou shell n'est PAS idempotent par défaut : il réexécute la commande à chaque run. Il faut ajouter une condition (creates:, when:) ou préférer un module déclaratif natif.

Terraform : état déclaratif et plan avant apply

Terraform maintient un fichier d'état qui reflète les ressources réellement provisionnées. La commande terraform plan calcule le différentiel entre l'état désiré (code) et l'état réel avant toute modification.

# main.tf — exemple de ressource idempotente
resource "aws_instance" "web" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"

tags = {
    Name        = "web-prod-01"
    ManagedBy   = "terraform"
    Environment = "production"
  }

lifecycle {
    prevent_destroy = true
  }
}

Attention

modifier une ressource manuellement dans la console cloud après un terraform apply crée une dérive (drift) entre l'état réel et l'état Terraform ; le prochain plan peut alors proposer de revenir en arrière et écraser la modification manuelle, parfois de façon destructive.

Comparatif rapide

CritèreAnsibleTerraform
ParadigmeImpératif ordonné, mais modules déclaratifsDéclaratif avec état
Cible typiqueConfiguration de systèmes existantsProvisioning de ressources cloud
IdempotenceDépend du module utiliséNative via le state
RollbackManuel (nouveau playbook)terraform plan + apply ciblé

Revue et tests avant application

Toute modification d'un playbook ou d'un module Terraform doit passer par une revue de code (pull request), un lint (ansible-lint, terraform validate), et idéalement un test en environnement isolé avant application en production.

ansible-lint playbook.yml
terraform fmt -check
terraform validate
terraform plan -out=tfplan

Sur le terrain

un incident fréquent survient lorsqu'un terraform apply est lancé sans relire le plan généré, notamment après une mise à jour de provider qui modifie silencieusement des attributs par défaut (ex. type de volume, politique de suppression) — la relecture systématique du plan est la meilleure protection.

Astuce

verrouillez les versions de providers Terraform et de collections Ansible dans un fichier de lock (.terraform.lock.hcl, requirements.yml avec versions épinglées) pour éviter qu'une mise à jour silencieuse ne change le comportement en production.

Leçon précédente