guest@6admin.io:~$

Terraform crée, Ansible configure

La remarque de Florian était honnête et je la partage dans sa première moitié : Terraform seul fonctionne très bien tant qu’on reste sur un modèle 100% immuable, où l’on balance un cloud-init au provisionnement, où l’on recrée la VM dès qu’il faut la changer et où rien ne se modifie en place. Si votre infra se prête à ce modèle, parfait, ne cherchez pas plus loin. La question intéressante commence à l’instant précis où elle ne s’y prête plus.

Deux outils, deux responsabilités

On mélange souvent l’Infrastructure as Code et la gestion de configuration parce que les deux vivent dans des fichiers texte versionnés et qu’on les range dans le même tiroir mental “automatisation”. Ce sont pourtant deux responsabilités distinctes.

Terraform, OpenTofu , Pulumi décrivent et réconcilient des ressources : une VM, un réseau, un bucket, une règle de firewall, un enregistrement DNS. Leur domaine, c’est l’existence et la forme de l’objet chez le provider, pas ce qui tourne à l’intérieur. Terraform sait très bien qu’une instance doit exister avec tel type et tel disque, il garde son state, il calcule le diff, il recrée ce qui a dérivé. Ce qu’il ne veut pas savoir, c’est quel service écoute sur quel port après le boot, ni dans quel état se trouve le fichier de conf à la trois-centième exécution.

Ansible, Salt, Puppet répondent justement à cette question-là : l’état désiré du système, de manière idempotente, avec un inventaire, des variables, des rôles réutilisables et un reporting. Leur domaine, c’est l’intérieur de la machine une fois qu’elle existe.

La formule tient en une ligne et elle résume l’essentiel : Terraform crée, Ansible configure et maintient.

Le modèle immuable, là où Terraform se suffit

Dans un monde strictement immuable, la frontière disparaît presque et c’est pour ça que le “Terraform tout seul” marche si bien quand il marche. On ne configure jamais une machine vivante : on construit une image en amont (avec Packer ou un pipeline qui cuit l’AMI), on la déploie et toute modification passe par une nouvelle image suivie d’une recréation. La VM devient un artefact jetable, le cloud-init ne fait qu’un amorçage minimal et l’état du système se confond avec l’état de l’infra que Terraform pilote déjà.

C’est élégant, c’est reproductible et quand l’architecture s’y prête (du stateless, du horizontalement scalable, des cycles de vie courts) il n’y a aucune raison d’ajouter un gestionnaire de configuration. J’ai vu des parcs entiers tenir sur ce modèle sans jamais qu’un ansible-playbook ait eu à tourner. Le piège n’est pas le modèle immuable en soi, il est de croire qu’on y est alors qu’on n’y est plus.

Le symptôme : remote-exec et le shell inline

Le moment où l’on quitte l’immuable est facile à dater, parce qu’il a une signature. Dès qu’il faut modifier quelque chose après la création de la VM, gérer des services, pousser des templates un peu complexes, enchaîner une mise à jour applicative ou simplement éviter d’écrire trois cents lignes de cloud-init, Terraform devient pénible. Et comme il faut bien que ça tourne, on sort le provisioner remote-exec, on colle du shell inline, on chaîne deux-trois local-exec et l’on se retrouve à faire de la gestion de configuration dans un outil qui n’a jamais été conçu pour ça.

Le résultat est connu : pas d’idempotence (le provisioner ne rejoue proprement que si vous codez vous-même la vérification), pas de reporting lisible, une exécution liée au cycle de vie de la ressource plutôt qu’à l’état du système et un state Terraform qui ne reflète plus la réalité de la machine puisque ce qui s’est passé dans le remote-exec lui est opaque. On n’a pas gagné en simplicité, on a juste déplacé la complexité dans un endroit où elle est illisible et fragile.

Le remote-exec, à mes yeux, n’est pas un outil, c’est un signal. Quand on commence à en avoir besoin, c’est que la frontière entre création et configuration vient d’être franchie et qu’il est temps de rendre à chaque outil son rôle.

Garder chaque outil dans son rôle

La répartition propre est sans surprise et c’est tant mieux. Terraform (ou OpenTofu) provisionne : il fait exister la VM, le réseau, le load balancer, l’enregistrement DNS et il garde ce périmètre réconcilié. Ansible prend le relais une fois la machine joignable : il installe, configure, template, met à jour et il reste rejouable à volonté sans casser ce qui est déjà en place. Chacun dans son rôle et les hacks disparaissent d’eux-mêmes, parce qu’on n’a plus à tordre un outil pour lui faire faire le travail de l’autre.

Le passage de relais mérite qu’on s’y attarde, parce que c’est là que les montages maison deviennent baroques : comment Ansible découvre-t-il ce que Terraform vient de créer ? La réponse artisanale consiste à faire cracher à Terraform un fichier d’inventaire et ça marche, mais ça recouple deux outils qu’on avait justement séparés. Je préfère découpler franchement et laisser l’inventaire se construire à partir d’une source de vérité que les deux consultent, le DNS par exemple, ce dont je parle dans l’inventaire par le DNS . Terraform y publie, Ansible y lit et aucun des deux ne dépend du state de l’autre.

Reste la question de fond, celle qu’on finit toujours par se poser : ai-je seulement besoin d’un gestionnaire de configuration ? Si tout tient en conteneurs immuables, le débat se déplace, parce que l’unité jetable n’est plus la VM mais l’image et c’est un autre sujet que j’aborde dans Docker et Ansible . Et avant de choisir l’outil, il vaut la peine de se rappeler d’où vient cette discipline de l’état désiré, bien antérieure à la mode, dont je parle dans l’ancêtre d’Ansible : le besoin est vieux, seuls les noms changent.

Où atterrir

Si votre infra est réellement immuable, du stateless, des images cuites en amont, des cycles courts, alors Terraform seul est le bon choix et ajouter un gestionnaire de configuration serait de la cérémonie inutile. Le jour où vous écrivez votre premier remote-exec pour autre chose qu’un amorçage trivial, ne le prenez pas pour un détail d’implémentation : c’est l’infra qui vous dit que vous avez quitté l’immuable et qu’il est temps de laisser Terraform créer et Ansible configurer, chacun à sa place, sans hack entre les deux.