
Vous avez compris le concept Terraform, installé l’outil, lu la documentation. Maintenant vient l’étape qui change tout : faire tourner votre première vraie infrastructure. Pas un exemple théorique — une VM qui démarre réellement sur votre machine locale avec KVM.
Ce guide vous fait créer en moins de 15 minutes une VM Ubuntu avec
Terraform et libvirt. Vous écrirez deux fichiers, lancerez quatre
commandes, et verrez la VM apparaître dans virsh list. C’est à partir
de cette base concrète que tout le reste prendra sens : variables, outputs,
modules, state.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Écrire les deux fichiers minimaux :
versions.tfetmain.tf - Exécuter le cycle complet :
init→validate→plan→apply - Observer le résultat :
virsh listpour confirmer que la VM existe - Lire le state : comprendre ce que Terraform a mémorisé
- Faire le ménage :
terraform destroypour supprimer proprement
Prérequis
Section intitulée « Prérequis »- Terraform ≥ 1.11 installé (installer Terraform)
- KVM/libvirt opérationnel (
kvm-okrenvoieKVM acceleration can be used) - Image Ubuntu 24.04 cloud disponible localement :
ls ~/images/ubuntu-24.04-cloudimg.imgSi l’image est absente, téléchargez-la :
mkdir -p ~/imageswget -O ~/images/ubuntu-24.04-cloudimg.img \ https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.imgStructure du projet
Section intitulée « Structure du projet »Analogie : un projet Terraform minimal, c’est comme une recette de cuisine avec deux fiches. La première fiche (versions.tf) indique les ustensiles nécessaires et leur version. La seconde (main.tf) décrit ce qu’on veut cuisiner. Terraform lit les deux fiches et prépare le résultat.
premiere-infra/├── versions.tf # Déclarations : version Terraform + provider libvirt└── main.tf # Ressources : le volume et la VMCréez le dossier de travail :
mkdir ~/premiere-infra && cd ~/premiere-infraÉtape 1 — versions.tf
Section intitulée « Étape 1 — versions.tf »Le fichier versions.tf déclare les dépendances du projet. Sans lui,
terraform init ne sait pas quel provider télécharger.
terraform { required_version = ">= 1.11.0" # Version minimale de Terraform requise required_providers { libvirt = { source = "dmacvicar/libvirt" # Auteur/nom du provider version = "~> 0.8" # ~> 0.8 = 0.8.x (patch autorisé, pas 0.9) } }}
provider "libvirt" { uri = "qemu:///system" # Se connecte au daemon libvirt local en root}Étape 2 — main.tf
Section intitulée « Étape 2 — main.tf »Le fichier main.tf déclare les ressources que Terraform doit créer.
Ici, deux ressources : un volume disque et une VM.
# --- Volume disque ---# Un volume libvirt expose un fichier .qcow2 dans un pool de stockage.# On part d'une image cloud existante (clonage au format qcow2).resource "libvirt_volume" "disk" { name = "premiere-infra.qcow2" # Nom du fichier dans le pool pool = "default" # Pool libvirt cible (default = /var/lib/libvirt/images/)
target = { format = { type = "qcow2" } # Format du disque virtuel } create = { content = { url = pathexpand("~/images/ubuntu-24.04-cloudimg.img") # Image source locale } }}
# --- Domaine (VM) ---# Un domaine libvirt correspond à une machine virtuelle KVM.resource "libvirt_domain" "vm" { name = "premiere-infra" # Nom de la VM dans libvirt type = "kvm" # Hyperviseur (kvm = virtualisation matérielle) memory = 512 # RAM en MiB memory_unit = "MiB" vcpu = 1 # Nombre de vCPUs
os = { type = "hvm" # Hardware Virtual Machine type_arch = "x86_64" # Architecture cible type_machine = "q35" # Chipset virtuel (q35 = moderne, recommandé) }
devices = { disks = [ { source = { file = { file = libvirt_volume.disk.path # Référence le volume créé ci-dessus } } target = { dev = "vda", bus = "virtio" } # Disque principal virtio } ] interfaces = [ { model = { type = "virtio" } source = { network = { network = "default" } } # Réseau libvirt par défaut } ] }}
# --- Output ---# Affiche le nom de la VM après l'apply.output "vm_name" { value = libvirt_domain.vm.name description = "Nom de la VM créée"}Étape 3 — Exécuter le cycle complet
Section intitulée « Étape 3 — Exécuter le cycle complet »-
Initialiser le projet
terraform inittélécharge le provider libvirt et prépare le répertoire.terraform/.Fenêtre de terminal terraform initRésultat attendu :
Initializing provider plugins...- Installing dmacvicar/libvirt v0.8.x...- Installed dmacvicar/libvirt v0.8.x (signed by a HashiCorp partner)Terraform has been successfully initialized! -
Vérifier la configuration
Fenêtre de terminal terraform validateSuccess! The configuration is valid. -
Prévisualiser les changements
Fenêtre de terminal terraform planTerraform affiche les ressources qu’il va créer. Chaque
+indique une création :Terraform will perform the following actions:# libvirt_volume.disk will be created+ resource "libvirt_volume" "disk" {+ name = "premiere-infra.qcow2"+ pool = "default"...}# libvirt_domain.vm will be created+ resource "libvirt_domain" "vm" {+ name = "premiere-infra"+ memory = 512...}Plan: 2 to add, 0 to change, 0 to destroy. -
Appliquer
Fenêtre de terminal terraform applyTerraform affiche le plan, puis demande confirmation. Tapez
yes:Do you want to perform these actions?Terraform will perform the actions described above.Only 'yes' will be accepted to approve.Enter a value: yeslibvirt_volume.disk: Creating...libvirt_volume.disk: Creation complete after 2slibvirt_domain.vm: Creating...libvirt_domain.vm: Creation complete after 1sApply complete! Resources: 2 added, 0 changed, 0 destroyed.Outputs:vm_name = "premiere-infra"
Étape 4 — Observer le résultat
Section intitulée « Étape 4 — Observer le résultat »Vérifiez que la VM existe dans libvirt :
virsh list --all Id Name State------------------------------- 1 premiere-infra runningVérifiez le volume disque :
virsh vol-list default | grep premiere premiere-infra.qcow2 /var/lib/libvirt/images/premiere-infra.qcow2Étape 5 — Explorer le state
Section intitulée « Étape 5 — Explorer le state »Le state mémorise ce que Terraform a créé. Pour lister les ressources :
terraform state listlibvirt_domain.vmlibvirt_volume.diskPour inspecter une ressource en détail :
terraform state show libvirt_domain.vm# libvirt_domain.vm:resource "libvirt_domain" "vm" { id = "abc123..." memory = 512 memory_unit = "MiB" name = "premiere-infra" type = "kvm" vcpu = 1 ...}Étape 6 — Détruire proprement
Section intitulée « Étape 6 — Détruire proprement »terraform destroyTerraform will destroy all managed objects.Do you really want to destroy all resources? Enter a value: yes
libvirt_domain.vm: Destroying...libvirt_domain.vm: Destruction complete after 1slibvirt_volume.disk: Destroying...libvirt_volume.disk: Destruction complete after 0s
Destroy complete! Resources: 2 destroyed.Terraform détruit dans l’ordre inverse de la création : la VM avant le volume.
À retenir
Section intitulée « À retenir »- Un projet Terraform minimal contient deux fichiers :
versions.tf+main.tf. - Le cycle est toujours :
init→validate→plan→apply. - Les références entre ressources (
libvirt_volume.disk.path) créent automatiquement les dépendances. - Le state mémorise ce qui a été créé — il est au cœur du fonctionnement.
terraform destroynettoie toutes les ressources dans l’ordre inverse.