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

Les data sources Terraform : lire l'existant

14 min de lecture

logo terraform

Vous déployez une VM sur un hyperviseur KVM qui a 64 Go de RAM. Vous voulez que votre configuration alloue automatiquement 25 % de la mémoire disponible — mais cette valeur dépend de la machine hôte, pas de votre code. Comment lire cette information depuis Terraform sans la coder en dur ?

Les data sources sont la réponse. Un bloc data {} ne crée, ne modifie et ne détruit rien — il lit uniquement. Il interroge une API ou l’infrastructure existante pendant le plan, et expose le résultat comme n’importe quel attribut de ressource. La puissance des data sources vient de leur intégration : vous pouvez référencer data.libvirt_node_info.host.memory dans vos ressources exactement comme var.nom ou libvirt_volume.disk.path. C’est le mécanisme standard pour connecter Terraform à de l’infrastructure existante non gérée par votre state.

  • Différence entre resource et data : créer vs lire
  • Syntaxe d’un bloc data {} et référence data.type.nom.attribut
  • Quand Terraform lit les data sources : dans le plan, pas l’apply
  • Utiliser une data source pour calculer des valeurs : sizing automatique d’une VM
  • Les data sources dans le state : data. dans terraform state list

Pensez à lire une API pour récupérer une valeur :

# Données en dur
memory = 64 # Codé manuellement
# Mieux : lire depuis l'API
api_response = requests.get("/api/host/memory")
memory = api_response["total_gb"] # 64
vm_memory = memory * 0.25 # 16 GB pour la VM
# Puis créer la VM
create_vm(name="my-vm", memory=vm_memory)

Les data sources de Terraform font exactement cela : au lieu de coder des valeurs manuellement, vous les lisez depuis une API ou de l’infra existante, puis les utilisez pour créer des ressources.

Caractéristiqueresourcedata
Crée un objetOuiNon
Modifie un objetOuiNon
Détruit un objetOuiNon
Lit des informationsEn retourUniquement
Lu au moment du…ApplyPlan par défaut, apply si dépendances inconnues
Présent dans le stateOuiOui

La ligne clé : Terraform essaie de lire les data sources pendant le plan, mais peut reporter cette lecture à l’apply si un argument dépend d’une valeur inconnue au moment du plan. Quand elles sont lues au plan, leurs valeurs sont disponibles pour calculer des attributs de ressources.

data "libvirt_node_info" "host" {}

La structure est identique aux ressources :

ÉlémentValeurRôle
Mot-clédataToujours data
Type de data source"libvirt_node_info"Défini par le provider
Nom local"host"Alias HCL libre

Pour référencer un attribut dans votre code :

data.type.nom_local.attribut

Exemple :

data.libvirt_node_info.host.memory_total_kb

Cet exemple illustre un cas concret : calculer automatiquement la mémoire à allouer à une VM en fonction des ressources réelles de l’hyperviseur.

mon-projet/
├── versions.tf ← provider libvirt
├── variables.tf ← vm_name, pool, image_path
├── main.tf ← data source + locals + ressources
└── outputs.tf ← infos host + mémoire calculée
# 1. Lire les infos du nœud KVM
data "libvirt_node_info" "host" {}
# 2. Calculer la mémoire VM depuis les infos lues
locals {
host_memory_mib = floor(data.libvirt_node_info.host.memory_total_kb / 1024)
vm_memory_mib = max(512, min(floor(local.host_memory_mib / 2), 4096))
}
# 3. Créer le disque
resource "libvirt_volume" "disk" {
name = "${var.vm_name}.qcow2"
pool = var.pool
target = { format = { type = "qcow2" } }
create = { content = { url = var.image_path } }
}
# 4. Créer la VM avec la mémoire calculée
resource "libvirt_domain" "vm" {
name = var.vm_name
memory = local.vm_memory_mib # ← vient de la data source
memory_unit = "MiB"
vcpu = 1
# ... reste de la config
}

Le flux est : datalocals (calcul) → resource (utilisation).

terraform plan — la data source est lue immédiatement

Section intitulée « terraform plan — la data source est lue immédiatement »
data.libvirt_node_info.host: Reading...
data.libvirt_node_info.host: Read complete after 0s [id=7280450332732970530]
Terraform will perform the following actions:
# libvirt_domain.vm will be created
+ memory = 4096
...
Changes to Outputs:
+ host_cpu_cores_total = 16
+ host_cpu_model = "x86_64"
+ host_memory_total_mib = 47953
+ vm_memory_allocated_mib = 4096

Le plan affiche déjà les valeurs réelles lues (host_cpu_cores_total = 16, host_memory_total_mib = 47953). La VM reçoit 4096 MiB — moitié de la RAM disponible (47953 MiB), plafonnée à 4096.

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
disk_path = "/var/lib/libvirt/images/lab05-vm.qcow2"
host_cpu_cores_total = 16
host_cpu_model = "x86_64"
host_memory_total_mib = 47953
vm_memory_allocated_mib = 4096
Fenêtre de terminal
terraform state list
data.libvirt_node_info.host ← data source, préfixe data.
libvirt_domain.vm
libvirt_volume.disk

Les data sources apparaissent dans le state, mais avec le préfixe data. Les inspecter avec terraform state show :

Fenêtre de terminal
terraform state show data.libvirt_node_info.host
# data.libvirt_node_info.host:
data "libvirt_node_info" "host" {
cpu_cores_per_socket = 16
cpu_cores_total = 16
cpu_model = "x86_64"
cpu_sockets = 1
cpu_threads_per_core = 1
id = "7280450332732970530"
memory_total_kb = 49104084
numa_nodes = 1
}

Terraform stocke le résultat lu pour détecter les changements lors des prochains plans. Si les données externes changent (nouvelle RAM dans le host), Terraform recalcule les valeurs dépendantes.

Les data sources couvrent principalement trois situations :

1. Lire de l’infrastructure gérée par une autre configuration Terraform

# Config équipe réseau (state A)
output "vpc_id" { value = aws_vpc.main.id }
# Votre config (state B)
data "terraform_remote_state" "network" {
backend = "s3"
config = { bucket = "...", key = "network/terraform.tfstate" }
}
resource "aws_subnet" "app" {
vpc_id = data.terraform_remote_state.network.outputs.vpc_id
}

2. Lire de l’infrastructure créée hors Terraform

# Pool libvirt créé manuellement (pas dans ce state)
data "libvirt_node_info" "host" {}
# Utiliser les infos dans une ressource
resource "libvirt_domain" "vm" {
memory = min(floor(data.libvirt_node_info.host.memory_total_kb / 1024 / 4), 2048)
}

3. Lire des informations dynamiques (IPs, états courants)

# Lire les interfaces d'une VM déjà créée
data "libvirt_domain_interface_addresses" "vm_ip" {
domain = libvirt_domain.vm.id
source = "lease"
}

Certaines data sources acceptent des arguments pour cibler précisément quoi lire. libvirt_node_info n’en a pas besoin (il n’y a qu’un seul hôte), mais libvirt_node_devices accepte un filtre :

data "libvirt_node_devices" "usb" {
capability = "usb_device"
}

Sur AWS, la data source aws_ami utilise des filtres pour trouver la bonne image :

# Note : exemple AWS théorique, non testé dans les labs du site
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-24.04-amd64-server-*"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # ← ID récupéré dynamiquement
instance_type = "t3.micro"
}

Terraform détermine l’ordre d’évaluation des data sources automatiquement :

  • Pas de dépendance sur une ressource → lue pendant le plan (avant apply)
  • Dépendance sur une ressource (known after apply) → lue après la creation de la ressource
# Cas 1 : lue pendant le plan (pas de dépendance)
data "libvirt_node_info" "host" {}
# Cas 2 : lue après création de la VM (dépendance sur libvirt_domain.vm)
data "libvirt_domain_interface_addresses" "ip" {
domain = libvirt_domain.vm.id # ← dépend d'une ressource
}

Dans le deuxième cas, Terraform affiche (known after apply) dans le plan pour les attributs qui dépendent de cette data source — et les lit lors de l’apply, une fois la VM créée.

SymptômeCause probableSolution
Error reading data source: connection refusedProvider non configuré ou service absentVérifier la config provider
Valeurs en (known after apply) dans le planData source dépend d’une ressource non crééeNormal — Terraform gère l’ordre
Error: data source not found in providerFaute de frappe sur le typeVérifier avec terraform providers schema -json
Data source non reconnue après initProvider pas à jourterraform init -upgrade
  1. data "type" "nom" {} lit sans jamais modifier l’infrastructure
  2. Les data sources sont lues pendant le plan (sauf si elles dépendent d’une ressource)
  3. La référence s’écrit data.type.nom.attribut — notez le préfixe data.
  4. Les data sources apparaissent dans terraform state list avec le préfixe data.
  5. Cas d’usage clés : infrastructure externe, autre state Terraform, infos dynamiques
  6. terraform state show data.type.nom affiche les valeurs lues

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