
Un projet Terraform peut tenir dans un seul fichier main.tf. Mais dès
qu’il dépasse quelques resources, la convention de découper en fichiers
thématiques améliore radicalement la lisibilité. Cette page présente la
structure standard, pourquoi elle existe, et comment l’appliquer dès le
premier projet.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Une convention recommandée :
versions.tf,main.tf,variables.tf,outputs.tf,terraform.tfvars - Le rôle de chaque fichier : ce qui va où et pourquoi
- Le fichier
.terraform.lock.hcl: à quoi il sert et pourquoi le commiter - Le
.gitignorerecommandé : ce qu’il ne faut jamais pousser dans Git
La structure minimale recommandée
Section intitulée « La structure minimale recommandée »Répertoiremon-projet/
- versions.tf (providers et contraintes de version)
- main.tf (resources et data sources)
- variables.tf (déclarations des variables)
- outputs.tf (valeurs exposées après apply)
- terraform.tfvars (valeurs des variables — ne pas commiter si sensible)
Terraform charge tous les fichiers .tf du répertoire courant. L’ordre
n’a pas d’importance — il résout les dépendances automatiquement.
Rôle de chaque fichier
Section intitulée « Rôle de chaque fichier »versions.tf
Section intitulée « versions.tf »Ce fichier déclare les contraintes sur Terraform lui-même et les providers requis. Il est la première chose à créer dans tout nouveau projet.
terraform { required_version = ">= 1.11.0" required_providers { libvirt = { source = "dmacvicar/libvirt" version = "~> 0.8" } }}Le cœur du projet : providers, resources, et data sources. Sur les petits
projets, tout tient ici. Sur les projets plus grands, on peut créer des
fichiers thématiques (network.tf, compute.tf, storage.tf).
provider "libvirt" { uri = "qemu:///system"}
resource "libvirt_volume" "disk" { name = var.vm_name pool = "default" target = { format = { type = "qcow2" } } create = { content = { url = var.image_path } }}
resource "libvirt_domain" "vm" { name = var.vm_name type = "kvm" memory = var.memory_mb memory_unit = "MiB" vcpu = var.vcpu_count
os = { type = "hvm" type_arch = "x86_64" type_machine = "q35" }
devices = { disks = [ { source = { file = { file = libvirt_volume.disk.path } } target = { dev = "vda", bus = "virtio" } } ] interfaces = [ { model = { type = "virtio" } source = { network = { network = "default" } } } ] }}variables.tf
Section intitulée « variables.tf »Toutes les déclarations variable {} sont regroupées ici. Ce fichier
documente les paramètres d’entrée du projet.
variable "vm_name" { description = "Nom de la VM libvirt" type = string default = "lab-vm"}
variable "memory_mb" { description = "RAM allouée en MiB" type = number default = 512}
variable "vcpu_count" { description = "Nombre de vCPUs" type = number default = 1}
variable "image_path" { description = "Chemin vers l'image cloud locale" type = string default = "/home/bob/images/ubuntu-24.04-cloudimg.img"}outputs.tf
Section intitulée « outputs.tf »Les valeurs à exposer après terraform apply : IP, nom, ID, chemin…
output "vm_name" { description = "Nom de la VM créée" value = libvirt_domain.vm.name}
output "disk_path" { description = "Chemin du disque dans le pool libvirt" value = libvirt_volume.disk.path}Après apply :
terraform output vm_name # → "lab-vm"terraform output disk_path # → "/var/lib/libvirt/images/lab-vm.qcow2"terraform.tfvars
Section intitulée « terraform.tfvars »Valeurs concrètes des variables. Ce fichier surcharge les default déclarés
dans variables.tf.
vm_name = "mon-serveur-web"memory_mb = 1024vcpu_count = 2La structure du projet testé
Section intitulée « La structure du projet testé »Voici la structure exacte du projet validé pour cette section :
Le fichier .terraform.lock.hcl
Section intitulée « Le fichier .terraform.lock.hcl »Généré automatiquement par terraform init, ce fichier enregistre les
versions exactes des providers installés et leur hash de vérification.
provider "registry.terraform.io/dmacvicar/libvirt" { version = "0.9.7" constraints = "~> 0.8" hashes = [ "h1:...", ]}Ce fichier doit être commité dans le dépôt Git. Il garantit que tous les membres de l’équipe installent exactement les mêmes versions de providers.
.gitignore recommandé
Section intitulée « .gitignore recommandé »# Terraform.terraform/terraform.tfstateterraform.tfstate.backup*.tfvars*.tfvars est exclu pour éviter de pousser des secrets. Si vos fichiers
.tfvars ne contiennent aucune donnée sensible, vous pouvez versionner un
fichier d’exemple (terraform.tfvars.example) ou retirer cette ligne.
.terraform.lock.hcl n’est pas dans le .gitignore — il doit
être versionné.
Structure pour un projet plus large
Section intitulée « Structure pour un projet plus large »Quand un projet grandit, on peut découper par type de ressource :
Répertoireinfra-kvm/
- versions.tf
- providers.tf (configurations des providers si multiples)
- network.tf (libvirt_network)
- compute.tf (libvirt_domain + libvirt_volume)
- variables.tf
- outputs.tf
- locals.tf (locals )
- terraform.tfvars
Il n’y a pas de règle absolue sur les noms de fichiers — l’essentiel est que la structure soit prévisible et documentée pour toute l’équipe.
À retenir
Section intitulée « À retenir »versions.tf: contraintes de version Terraform et providers.main.tf: provider, resources, data sources.variables.tf: déclarations des paramètres d’entrée.outputs.tf: valeurs exposées après apply.terraform.tfvars(et*.auto.tfvars) : valeurs des variables (hors secrets)..terraform.lock.hcl: à commiter impérativement..terraform/etterraform.tfstate: à exclure du Git.