Aller au contenu
Infrastructure as Code medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Première infrastructure Terraform sur KVM

11 min de lecture

logo terraform

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.

  • Écrire les deux fichiers minimaux : versions.tf et main.tf
  • Exécuter le cycle complet : initvalidateplanapply
  • Observer le résultat : virsh list pour confirmer que la VM existe
  • Lire le state : comprendre ce que Terraform a mémorisé
  • Faire le ménage : terraform destroy pour supprimer proprement
  • Terraform ≥ 1.11 installé (installer Terraform)
  • KVM/libvirt opérationnel (kvm-ok renvoie KVM acceleration can be used)
  • Image Ubuntu 24.04 cloud disponible localement :
Fenêtre de terminal
ls ~/images/ubuntu-24.04-cloudimg.img

Si l’image est absente, téléchargez-la :

Fenêtre de terminal
mkdir -p ~/images
wget -O ~/images/ubuntu-24.04-cloudimg.img \
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

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 VM

Créez le dossier de travail :

Fenêtre de terminal
mkdir ~/premiere-infra && cd ~/premiere-infra

Le fichier versions.tf déclare les dépendances du projet. Sans lui, terraform init ne sait pas quel provider télécharger.

versions.tf
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
}

Le fichier main.tf déclare les ressources que Terraform doit créer. Ici, deux ressources : un volume disque et une VM.

main.tf
# --- 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"
}
  1. Initialiser le projet

    terraform init télécharge le provider libvirt et prépare le répertoire .terraform/.

    Fenêtre de terminal
    terraform init

    Ré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!
  2. Vérifier la configuration

    Fenêtre de terminal
    terraform validate
    Success! The configuration is valid.
  3. Prévisualiser les changements

    Fenêtre de terminal
    terraform plan

    Terraform 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.
  4. Appliquer

    Fenêtre de terminal
    terraform apply

    Terraform 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: yes
    libvirt_volume.disk: Creating...
    libvirt_volume.disk: Creation complete after 2s
    libvirt_domain.vm: Creating...
    libvirt_domain.vm: Creation complete after 1s
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    Outputs:
    vm_name = "premiere-infra"

Vérifiez que la VM existe dans libvirt :

Fenêtre de terminal
virsh list --all
Id Name State
-------------------------------
1 premiere-infra running

Vérifiez le volume disque :

Fenêtre de terminal
virsh vol-list default | grep premiere
premiere-infra.qcow2 /var/lib/libvirt/images/premiere-infra.qcow2

Le state mémorise ce que Terraform a créé. Pour lister les ressources :

Fenêtre de terminal
terraform state list
libvirt_domain.vm
libvirt_volume.disk

Pour inspecter une ressource en détail :

Fenêtre de terminal
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
...
}
Fenêtre de terminal
terraform destroy
Terraform 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 1s
libvirt_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.

  • Un projet Terraform minimal contient deux fichiers : versions.tf + main.tf.
  • Le cycle est toujours : initvalidateplanapply.
  • 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 destroy nettoie toutes les ressources dans l’ordre inverse.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn