Passer au contenu principal

Fondamentaux (Terraform)

Ressources et data sources

Les ressources et les data sources sont les deux briques fondamentales d'un projet Terraform. Les ressources créent et gèrent des objets d'infrastructure. Les data sources interrogent des ressources existantes sans les gérer. Maîtriser les meta-arguments qui s'appliquent à toutes les ressources donne un contrôle fin sur le comportement de Terraform.

Ressources

Syntaxe : resource "TYPE" "NOM_LOCAL" { ... }. Le type combine le provider et le type de ressource. Le nom local est l'identifiant dans le code Terraform.

resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "main-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id    # référence à la ressource ci-dessus
  cidr_block        = "10.0.1.0/24"
  availability_zone = "eu-west-1a"
}

La référence aws_vpc.main.id crée une dépendance implicite : Terraform créera le VPC avant le subnet.

Data sources

Un data source lit des informations sur une ressource existante (créée manuellement ou par un autre projet Terraform) :

# Récupérer l'AMI Debian 13 la plus récente
data "aws_ami" "debian13" {
  most_recent = true
  owners      = ["136693071363"]    # compte officiel Debian

  filter {
    name   = "name"
    values = ["debian-13-amd64-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.debian13.id    # utilise le data source
  instance_type = "t3.micro"
}

Meta-arguments essentiels

depends_on : dépendance explicite quand la dépendance implicite ne suffit pas.

resource "aws_instance" "app" {
  # ...
  depends_on = [aws_iam_role_policy.app_policy]
}

count : créer N instances identiques d'une ressource.

resource "aws_instance" "web" {
  count         = 3
  ami           = data.aws_ami.debian13.id
  instance_type = "t3.micro"

  tags = {
    Name = "web-${count.index}"
  }
}

# Référencer une instance spécifique
output "first_ip" {
  value = aws_instance.web[0].public_ip
}

# Référencer toutes les instances
output "all_ips" {
  value = aws_instance.web[*].public_ip
}

for_each : préféré à count pour les collections nommées. Évite les recréations en cascade lors de suppressions.

variable "servers" {
  default = {
    web1 = { type = "t3.micro",  az = "eu-west-1a" }
    web2 = { type = "t3.small",  az = "eu-west-1b" }
    db1  = { type = "t3.medium", az = "eu-west-1a" }
  }
}

resource "aws_instance" "servers" {
  for_each      = var.servers
  ami           = data.aws_ami.debian13.id
  instance_type = each.value.type
  availability_zone = each.value.az

  tags = { Name = each.key }
}

output "server_ips" {
  value = { for k, v in aws_instance.servers : k => v.public_ip }
}

lifecycle : contrôle le comportement lors des mises à jour et des suppressions.

resource "aws_db_instance" "main" {
  # ...
  lifecycle {
    prevent_destroy       = true   # empêche terraform destroy sur cette ressource
    create_before_destroy = true   # recréer avant de détruire (zero-downtime)
    ignore_changes        = [tags] # ignorer les changements sur ce champ
  }
}