Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1415 minIntermédiaire

Terraform et OpenTofu : les notions

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • distinguer provisionnement et gestion de configuration ;
  • lire une configuration Terraform simple ;
  • expliquer le cycle init, plan, apply, destroy et le rôle de l'état ;
  • choisir entre Terraform et OpenTofu, et les combiner avec Ansible.

3 exercices corrigés1 schéma

Terraform et OpenTofu sont des outils d'infrastructure as code qui créent l'infrastructure (machines virtuelles, réseaux, stockage, ressources cloud) à partir de fichiers déclaratifs écrits en HCL, en gardant un état de ce qu'ils ont créé. Ils complètent Ansible, qui configure ensuite les machines. Ce chapitre explique la différence entre provisionnement et gestion de configuration, les notions de Terraform (fournisseur, ressource, plan, état), un exemple sur Proxmox VE, et la façon de combiner les deux outils.

Provisionner ou configurer

On distingue deux étapes dans la vie d'un serveur :

  • le provisionnement (provisioning, souvent appelé « jour 0 ») : faire exister la machine, avec son processeur, sa mémoire, son disque, sa carte réseau, son adresse ;
  • la gestion de configuration (« jour 1 » et suivants) : installer et régler ce qui tourne dessus, puis le maintenir dans le temps.
Terraform, OpenTofuAnsible
Métier principalCréer, modifier, détruire des ressources d'infrastructureConfigurer des systèmes existants, déployer, orchestrer
StyleDéclaratif : l'ensemble des ressources vouluesDéclaratif par tâche, procédural par playbook
LangageHCL (HashiCorp Configuration Language)YAML et Jinja2
Mémoire de ce qui existeUn fichier d'état (terraform.tfstate)Aucune : chaque exécution observe l'état réel
Avant d'agirplan : la liste exacte de ce qui sera créé, modifié, détruit--check --diff : une simulation, moins complète
Supprimer ce qui n'est plus décritOui : une ressource retirée du code est détruiteNon : il faut écrire une tâche state: absent
CibleAPI (Proxmox, VMware, clouds, DNS, pare-feu…)SSH, WinRM, API

L'état fait la différence. Ansible ne se souvient de rien : si tu retires une VM de ton playbook, elle continue d'exister. Terraform sait ce qu'il a créé : si tu retires la VM du code, le plan suivant annonce sa destruction.

Terraform et OpenTofu

Terraform a été créé par HashiCorp en 2014. En août 2023, HashiCorp a remplacé sa licence libre (MPL 2.0) par la Business Source License (BSL 1.1) à partir de la version 1.6 : le code reste lisible et utilisable en interne, mais n'est plus un logiciel libre au sens de l'OSI, et ne peut pas servir à bâtir un produit concurrent. HashiCorp appartient à IBM depuis 2025. En novembre 2026, la version courante est la 1.17.

OpenTofu est le fork libre de Terraform, né de ce changement de licence à partir de la dernière version sous MPL 2.0. Il est hébergé par la Linux Foundation et accepté à la CNCF depuis 2025. Il garde le même langage, les mêmes fichiers et la même compatibilité avec les fournisseurs ; la commande s'appelle tofu au lieu de terraform. Sa version courante est la 1.13.

Pour un laboratoire ou une PME, les deux conviennent ; OpenTofu a l'avantage d'une licence libre et d'une gouvernance ouverte. Tout ce chapitre s'applique aux deux, en remplaçant terraform par tofu dans les commandes.

Les notions de base

NotionDéfinitionExemple
Fournisseur (provider)Le greffon qui sait parler à une APIbpg/proxmox pour Proxmox VE
Ressource (resource)Un objet d'infrastructure à créer et gérerUne VM, un enregistrement DNS
Source de données (data source)Une information lue sans être géréeLa liste des nœuds du cluster
VariableUne valeur d'entréeLe jeton d'API, le nombre de VM
Sortie (output)Une valeur affichée ou transmise à la finL'adresse de la VM créée
État (state)Le fichier qui mémorise les ressources créées et leurs attributsterraform.tfstate
ModuleUn ensemble réutilisable de ressources« Une VM Debian standard »

Le cycle de travail tient en quatre commandes :

bash
terraform init       # télécharge les fournisseurs, prépare le dossier
terraform plan       # compare le code, l'état et la réalité : affiche ce qui va changer
terraform apply      # applique le plan, après confirmation
terraform destroy    # détruit tout ce que le code a créé

plan est le moment clé : il dit exactement, ressource par ressource, ce qui sera créé (+), modifié (~), détruit (-) ou remplacé (-/+, détruit puis recréé), avec un résumé du type Plan: 1 to add, 0 to change, 0 to destroy. On relit le plan avant de valider ; en équipe, on le joint à la demande de fusion.

Un exemple sur Proxmox VE

Le fournisseur communautaire bpg/proxmox est aujourd'hui le plus utilisé pour Proxmox VE (l'ancien fournisseur telmate/proxmox est très peu maintenu). Le fichier main.tf qui crée la même VM de recette qu'au chapitre 13, avec le même jeton d'API :

hcl
terraform {
  required_providers {
    proxmox = {
      source  = "bpg/proxmox"
      version = "~> 0.120"
    }
  }
}

variable "jeton_proxmox" {
  description = "Jeton d'API, au format ansible@pve!automatisation=secret"
  type        = string
  sensitive   = true
}

provider "proxmox" {
  endpoint  = "https://192.168.10.213:8006/"
  api_token = var.jeton_proxmox
  insecure  = true
}

resource "proxmox_virtual_environment_vm" "recette" {
  name      = "srv-recette"
  node_name = "pve1"
  vm_id     = 186

  clone {
    vm_id = 9000
    full  = true
  }

  cpu {
    cores = 4
  }

  memory {
    dedicated = 8192
  }

  disk {
    datastore_id = "truenas-nfs"
    interface    = "scsi0"
    size         = 40
  }

  network_device {
    bridge  = "vmbr0"
    vlan_id = 21
  }

  initialization {
    datastore_id = "truenas-nfs"

    ip_config {
      ipv4 {
        address = "192.168.21.186/24"
        gateway = "192.168.21.254"
      }
    }

    dns {
      domain  = "ad.sorbier.example"
      servers = ["192.168.10.177", "192.168.10.181"]
    }

    user_account {
      username = "ansible"
      keys     = [trimspace(file(pathexpand("~/.ssh/ansible_ed25519.pub")))]
    }
  }
}

output "adresse_recette" {
  value = "192.168.21.186"
}

Lis-le comme un inventaire de ce qui doit exister : un bloc terraform qui déclare le fournisseur et sa version, une variable sensible (sa valeur n'apparaît pas dans les sorties), le fournisseur configuré, puis une ressource de type proxmox_virtual_environment_vm, nommée recette dans le code, dont chaque bloc décrit une partie de la VM. insecure = true accepte le certificat auto-signé de Proxmox, comme validate_certs: false côté Ansible.

Le secret ne s'écrit pas dans le fichier : il passe par une variable d'environnement, que Terraform lit automatiquement pour la variable du même nom.

bash
export TF_VAR_jeton_proxmox='ansible@pve!automatisation=a1b2c3d4-e5f6-7890-abcd-ef1234567890'
terraform init
terraform plan
terraform apply

Change ensuite cores = 4 en cores = 2 : le plan annonce une modification en place (~). Supprime le bloc resource : le plan annonce une destruction. C'est ce suivi qui fait l'intérêt de l'outil.

L'état : précieux et sensible

Le fichier terraform.tfstate est la mémoire de Terraform. S'il est perdu, Terraform ne sait plus qu'il a créé la VM et voudra la recréer ; si deux personnes l'utilisent en même temps, il peut être corrompu.

  • Ne le mets pas dans Git. Il contient les attributs des ressources, souvent des secrets en clair. Il va dans le .gitignore, avec le dossier .terraform/ des fournisseurs téléchargés.
  • En équipe, range-le dans un backend distant avec verrouillage : un stockage objet compatible S3, la base PostgreSQL d'un serveur interne, ou le service de l'éditeur. Chaque exécution prend un verrou, et les autres attendent.
  • OpenTofu sait chiffrer l'état côté client ; Terraform n'a pas cette fonction et compte sur le chiffrement du backend qui stocke l'état.

Terraform et Ansible ensemble

Les deux outils se complètent naturellement : Terraform crée les VM, Ansible les configure.

Dépôt Gitsorbier-infraterraform/roles/, site.ymlPipeline CIvalidate, planansible-lint--syntax-checkà chaque push1. Terraform ou OpenTofucrée les VM par l'APIde Proxmox VE, port 8006état : backend verrouillé2. Ansiblese connecte en SSHapplique les rôlessocle et webaprèsfusionadresses des VMVM configuréessrv-recettesrv-test1même code,même résultatcréeconfigureTerraform répond à « quelles machines existent ? »Ansible répond à « comment sont-elles configurées ? »
Terraform crée les machines, Ansible les configure, le dépôt Git et la CI encadrent les deux

Trois façons de faire passer les adresses de Terraform à Ansible :

  1. Les sorties de Terraform (terraform output -json) lues par un script qui écrit l'inventaire ;
  2. un inventaire dynamique qui interroge directement l'hyperviseur, comme celui du chapitre 13 ;
  3. le DNS : les VM sont déclarées dans le DNS et l'inventaire utilise leurs noms.

Le dépôt de Sorbier range les deux outils côte à côte (terraform/ et le reste du projet Ansible), et le pipeline d'intégration continue vérifie les deux (chapitre 15).

Exercices

Exercice 1 sur 3 Quel outil ? Réussi À revoir

Pour chaque tâche, dis si elle relève plutôt de Terraform ou OpenTofu, ou plutôt d'Ansible.

  1. Créer trois VM sur le cluster Proxmox et les supprimer quand le projet se termine.
  2. Installer Apache et déployer l'hôte virtuel du site de suivi.
  3. Créer les enregistrements DNS d'une zone publique chez un hébergeur qui propose une API.
  4. Créer 25 comptes Active Directory à partir d'une liste.
  5. Ajouter 4 Gio de mémoire à une VM existante créée par Terraform.
Voir la réponseMasquer la réponse de l'exercice 1
  1. Terraform ou OpenTofu : création et destruction de ressources, suivies par l'état.
  2. Ansible : configuration du système.
  3. Terraform ou OpenTofu : ce sont des ressources d'infrastructure exposées par une API, et l'état permet de supprimer proprement un enregistrement retiré du code. Ansible sait aussi le faire avec un module de l'hébergeur.
  4. Ansible (microsoft.ad.user) : on configure un service existant, l'annuaire.
  5. Terraform : la VM est décrite dans son code ; il faut y changer dedicated. La modifier par Ansible ou à la main créerait un écart que le plan suivant voudrait annuler.

Tu avais trouvé ?

Exercice 2 sur 3 Lire un plan Réussi À revoir

Après une modification du code, terraform plan affiche pour la VM de recette -/+ resource "proxmox_virtual_environment_vm" "recette" et le résumé Plan: 1 to add, 0 to change, 1 to destroy. Que va-t-il se passer si tu valides ? Que fais-tu avant ?

Voir la réponseMasquer la réponse de l'exercice 2

-/+ signifie remplacement : Terraform va détruire la VM 186 puis en créer une nouvelle. Le résumé le confirme : une destruction et une création. Toutes les données de la VM (et sa configuration faite par Ansible) seront perdues. Avant de valider : chercher dans le plan quel attribut force le remplacement (Terraform l'indique par # forces replacement), se demander si la modification est vraiment voulue ou si un changement en place est possible, et vérifier qu'une sauvegarde récente existe. Sur une VM de recette jetable, c'est acceptable ; sur une VM de production, jamais sans préparation.

Tu avais trouvé ?

Exercice 3 sur 3 L'état dans Git ? Réussi À revoir

Moussa propose de commiter terraform.tfstate dans le dépôt, « pour que tout le monde ait le même état ». Donne deux raisons de refuser et la bonne solution.

Voir la réponseMasquer la réponse de l'exercice 3
  1. Les secrets : l'état contient les attributs des ressources, parfois des mots de passe ou des clés en clair ; il serait lisible par tous ceux qui lisent le dépôt, et resterait dans l'historique.
  2. Les conflits et la corruption : deux administrateurs qui appliquent en même temps à partir de deux copies de l'état divergent ; Git ne sait pas fusionner un état, et l'un écrase le travail de l'autre.

La bonne solution est un backend distant avec verrouillage (stockage objet compatible S3, PostgreSQL, service de l'éditeur), accessible aux seuls administrateurs, et le fichier terraform.tfstate dans le .gitignore.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Versionner l'infrastructure : Git, Galaxy, ansible-lint et CIRevoir le sommaire du cours