Retour au cours

infra / terraform

Data sources : lire l'existant

Leçon 61 exercice

Explication

Ce que vous allez apprendre

  • Distinguer une resource (qui crée) d'une data source (qui lit)
  • Récupérer dynamiquement la dernière AMI Ubuntu disponible sans coder un ID en dur
  • Référencer une infrastructure partagée gérée par une autre équipe
  • Lire des informations sur le compte ou la session cloud active
  • Reconnaître les cas d'usage typiques où une data source est préférable à une valeur codée en dur

Dans quel contexte ?

La configuration Terraform de l'équipe utilise depuis plusieurs leçons l'ID d'AMI codé en dur ami-0c55b159cbfafe1f0. Ce problème, déjà signalé, devient concret le jour où cette AMI est dépréciée par AWS et où le prochain apply échoue avec une erreur "AMI not found" — alors que rien n'a changé dans le code lui-même.

D'abord, il faut comprendre la distinction fondamentale entre resource et data

Une resource dit à Terraform "crée et gère cet objet, du début à la fin de son cycle de vie". Une data source, elle, dit l'inverse : "va LIRE cet objet qui existe déjà, mais ne le gère pas, ne le modifie jamais et ne le détruit jamais".

Cette distinction est essentielle : un terraform destroy ne touchera JAMAIS à une ressource référencée uniquement via une data source, même si cette ressource est mentionnée explicitement dans le fichier de configuration.

resourcedata
Action de TerraformCrée, modifie, détruitLit seulement
Impact d'un destroySupprime l'objetAucun impact
Cas d'usage typiqueUn bucket S3, une instance EC2 propre au projetUne AMI officielle, un VPC partagé, l'identité du compte actif

Prérequis

Cette leçon suppose que tu es à l'aise avec la syntaxe des blocs resource et les références entre ressources (type.nom.attribut), vues dans une leçon précédente — les data sources se référencent de façon très similaire.

Une fois cette distinction comprise, résolvons le problème de l'AMI codée en dur

data "aws_ami" "ubuntu_dernier" avec most_recent = true et un filtre sur le nom d'image demande à AWS "quelle est la dernière AMI Ubuntu 22.04 disponible, à l'instant présent ?". Le résultat s'utilise ensuite exactement comme un attribut de ressource classique, via data.aws_ami.ubuntu_dernier.id.

Il reste un autre cas d'usage très fréquent en entreprise : référencer une infrastructure gérée ailleurs

Souvent, le réseau (VPC, sous-réseaux) est géré par une équipe infrastructure séparée, dans un projet Terraform différent. Plutôt que de dupliquer cette configuration réseau, une équipe applicative peut simplement LIRE ce VPC existant via data "aws_vpc", en le filtrant par un tag connu.

Astuce

data.aws_caller_identity.courant (compte AWS actif) et data.aws_region.courant (région active) permettent d'écrire une configuration qui s'adapte automatiquement selon l'environnement dans lequel elle s'exécute, sans jamais coder ces valeurs en dur — utile notamment pour construire des ARN dynamiquement.

Le piège à connaître avant de continuer

Piège fréquent

Une data source échoue si AUCUN résultat ne correspond aux filtres fournis, ou si PLUSIEURS résultats correspondent alors qu'un seul est attendu. Vérifie toujours que tes filtres sont suffisamment précis (comme la combinaison name + virtualization-type de cette leçon) pour cibler exactement un seul objet.

Maintenant que tu sais lire l'existant, la prochaine leçon aborde le passage à l'échelle : comment regrouper des ressources en modules réutilisables, plutôt que de tout répéter dans un seul fichier plat.

Commandes & code

Data sources : lire l'existant

hcl
# Une "resource" CRÉE quelque chose ; une "data source" LIT quelque chose qui existe déjà
data "aws_ami" "ubuntu_dernier" {
  most_recent = true
  owners      = ["099720109477"]              # Canonical (éditeur d'Ubuntu)

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu_dernier.id    # utilise l'AMI trouvée dynamiquement
  instance_type = "t3.micro"
}

# Lire un VPC existant créé manuellement ou par une autre équipe
data "aws_vpc" "principal" {
  filter {
    name   = "tag:Name"
    values = ["vpc-production"]
  }
}

data "aws_subnets" "prives" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.principal.id]
  }
  tags = {
    Tier = "private"
  }
}

resource "aws_instance" "app" {
  ami           = data.aws_ami.ubuntu_dernier.id
  instance_type = "t3.micro"
  subnet_id     = data.aws_subnets.prives.ids[0]      # premier sous-réseau privé trouvé
}

# Lire des informations sur le compte/la session AWS courante
data "aws_caller_identity" "courant" {}

output "compte_aws" {
  value = data.aws_caller_identity.courant.account_id
}
bash
# Cas d'usage typiques des data sources :
# - Récupérer la dernière AMI officielle sans en coder l'ID en dur (qui change à chaque release)
# - Référencer une infra partagée (VPC, zone DNS) gérée dans un AUTRE state Terraform
# - Adapter dynamiquement la config selon le compte/la région active (data.aws_caller_identity, data.aws_region)

Résumé

  • Les data sources lisent des ressources existantes sans les gérer (pas de création/destruction par Terraform).
  • Elles évitent de coder en dur des IDs qui changent (AMI, AZ disponibles) ou de dupliquer une infra déjà créée ailleurs.
  • filter combine plusieurs critères pour cibler précisément la ressource à lire.

Exercices pratiques

1 disponible
1

Mission : fiabiliser une AMI qui vient de disparaître

Objectif : Remplacer une valeur codée en dur par une lecture dynamique, et raisonner sur ce qu'une data source protège vraiment.

Contexte

Une équipe ajoute par précipitation un data "aws_ami" "ubuntu_dernier" avec seulement owners = ["099720109477"], sans filtre name précis. terraform plan échoue avec une erreur indiquant que plusieurs résultats correspondent aux critères. Par ailleurs, un data "aws_vpc" "principal" est référencé dans plusieurs ressources applicatives du même projet.

Résoudre l’exercice →