Leçon 4 / 6
Leçon 04 · Partie 2 — Structurer son code

Variables et outputs

Pourquoi des variables ?

Écrire des valeurs en dur dans le code Terraform, c'est le meilleur moyen de devoir tout modifier quand tu changes d'environnement. Les variables d'entrée permettent de paramétrer ta configuration : tu définis le "quoi" une seule fois, et tu fournis le "combien" séparément selon le contexte (dev, staging, production).

Le bloc variable

Un bloc variable déclare une variable d'entrée. Il peut contenir un type, une valeur par défaut et une description.

variables.tf
# Variable de type string avec valeur par défaut
variable "region" {
  type        = string
  default     = "eu-west-1"
  description = "Région AWS cible"
}

# Variable sans valeur par défaut — obligatoire à fournir
variable "instance_type" {
  type        = string
  description = "Type d'instance EC2 (ex : t3.micro)"
}

# Variable numérique
variable "instance_count" {
  type        = number
  default     = 1
  description = "Nombre d'instances à créer"
}

Pour utiliser une variable dans ta configuration, on écrit var.nom_variable.

main.tf
provider "aws" {
  region = var.region
}

resource "aws_instance" "web" {
  instance_type = var.instance_type
  count         = var.instance_count
}

Types de variables

Terraform supporte plusieurs types primitifs et structurés :

Type Exemple de valeur Usage typique
string "eu-west-1" Région, nom, identifiant
number 3 Compteur, port, taille
bool true Activer/désactiver une feature
list(string) ["a", "b", "c"] Liste de sous-réseaux, de zones
map(string) {"env" = "prod"} Tags, paires clé/valeur
object({…}) Objet structuré Configuration complexe typée
variables.tf — types complexes
variable "availability_zones" {
  type    = list(string)
  default = ["eu-west-1a", "eu-west-1b"]
}

variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Project     = "monminilab"
  }
}

variable "db_config" {
  type = object({
    engine  = string
    version = string
    port    = number
  })
  default = {
    engine  = "postgres"
    version = "15"
    port    = 5432
  }
}

Passer des valeurs aux variables

Il existe plusieurs façons de fournir une valeur à une variable :

1. Fichier terraform.tfvars

C'est la méthode recommandée. Terraform charge automatiquement ce fichier si il est présent dans le répertoire de travail.

terraform.tfvars
region         = "eu-west-3"
instance_type  = "t3.micro"
instance_count = 2

tags = {
  Environment = "production"
  Project     = "monminilab"
}

2. Argument -var en ligne de commande

Terminal
# Passer une variable directement
terraform apply -var="instance_type=t3.small"

# Utiliser un fichier de variables personnalisé
terraform apply -var-file="prod.tfvars"

3. Variables d'environnement TF_VAR_

Toute variable d'environnement préfixée par TF_VAR_ est automatiquement lue par Terraform. Pratique dans les pipelines CI/CD.

Terminal
# Bash / Linux / macOS
export TF_VAR_region="eu-west-3"
export TF_VAR_instance_type="t3.micro"
terraform apply

Les locals — valeurs calculées et réutilisées

Le bloc locals permet de définir des valeurs calculées ou dérivées à l'intérieur de la configuration. Contrairement aux variables, les locals ne sont pas fournis de l'extérieur : ils sont calculés une fois et réutilisés partout. On y accède via local.nom.

locals.tf
locals {
  # Concaténation de chaînes
  name_prefix = "${var.tags["Project"]}-${var.tags["Environment"]}"

  # Valeur conditionnelle
  is_prod = var.tags["Environment"] == "production"

  # Tags communs enrichis d'une date
  common_tags = merge(var.tags, {
    ManagedBy = "Terraform"
  })
}

resource "aws_instance" "web" {
  # Réutilisation du local
  tags = local.common_tags
}

Les outputs — exposer des valeurs après apply

Les outputs permettent d'afficher des informations importantes après un terraform apply, et d'exposer des valeurs à d'autres configurations Terraform. On les déclare dans le bloc output.

outputs.tf
output "instance_public_ip" {
  description = "Adresse IP publique de l'instance EC2"
  value       = aws_instance.web.public_ip
}

output "instance_id" {
  description = "Identifiant AWS de l'instance"
  value       = aws_instance.web.id
}

output "availability_zone" {
  description = "Zone de disponibilité utilisée"
  value       = aws_instance.web.availability_zone
}

Après un apply, Terraform affiche les outputs dans le terminal. Tu peux aussi les consulter à tout moment avec terraform output.

Terminal — après terraform apply
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

instance_public_ip  = "54.76.12.44"
instance_id         = "i-0abc1234def56789"
availability_zone   = "eu-west-1a"

Variables sensibles — sensitive = true

Certaines variables contiennent des secrets : mots de passe, clés API, tokens. En ajoutant sensitive = true, Terraform masque leur valeur dans les logs et dans la sortie du plan ou de l'apply. La valeur reste dans le state — protège ton fichier state en conséquence.

variables.tf — valeurs sensibles
variable "db_password" {
  type        = string
  sensitive   = true
  description = "Mot de passe de la base de données"
}

# Un output peut aussi être marqué sensible
output "db_connection_string" {
  description = "Chaîne de connexion complète"
  value       = "postgres://admin:${var.db_password}@${aws_db_instance.main.endpoint}/app"
  sensitive   = true
}
⚠️

Même avec sensitive = true, la valeur est stockée en clair dans le fichier terraform.tfstate. Ne commite jamais ce fichier dans Git, et utilise un backend distant (S3, Terraform Cloud) avec chiffrement activé pour les projets sensibles.

Interpolation dans les strings

Terraform utilise la syntaxe ${…} pour insérer des expressions dans des chaînes de caractères. Tu peux y placer des variables, des locals, des attributs de ressources ou des fonctions.

main.tf — interpolation
resource "aws_s3_bucket" "logs" {
  # Interpolation de variable
  bucket = "${var.tags["Project"]}-logs-${var.region}"

  tags = {
    # Interpolation d'un local
    Name = "${local.name_prefix}-bucket"
  }
}

output "bucket_url" {
  # Interpolation d'un attribut de ressource
  value = "https://${aws_s3_bucket.logs.bucket_regional_domain_name}"
}

Exemple complet

Un exemple concret : une instance EC2 paramétrée avec des variables régionales et de taille, exposant l'adresse IP publique en output.

variables.tf
variable "region" {
  type        = string
  default     = "eu-west-3"
  description = "Région AWS"
}

variable "instance_type" {
  type        = string
  default     = "t3.micro"
  description = "Taille de l'instance EC2"
}

variable "ami_id" {
  type        = string
  description = "AMI à utiliser (Amazon Machine Image)"
}
main.tf
provider "aws" {
  region = var.region
}

locals {
  instance_name = "web-${var.region}"
}

resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = var.instance_type

  tags = {
    Name      = local.instance_name
    ManagedBy = "Terraform"
  }
}
outputs.tf
output "public_ip" {
  description = "IP publique de l'instance web"
  value       = aws_instance.web.public_ip
}

output "instance_name" {
  description = "Nom de l'instance"
  value       = local.instance_name
}
terraform.tfvars
region        = "eu-west-3"
instance_type = "t3.small"
ami_id        = "ami-0c02fb55956c7d316"
// À retenir
  • variable déclare une entrée paramétrée ; var.nom pour y accéder.
  • Types disponibles : string, number, bool, list, map, object.
  • Valeurs passées via terraform.tfvars, flag -var ou TF_VAR_.
  • locals centralise les valeurs calculées ; local.nom pour y accéder.
  • output expose des valeurs après apply — utile pour chaîner des configurations.
  • sensitive = true masque une variable dans les logs mais pas dans le state.