infra / terraform
Variables et outputs
Explication
Ce que vous allez apprendre
- Déclarer des variables typées avec valeur par défaut, description et validation
- Protéger une valeur sensible avec
sensitive = true - Exposer des valeurs utiles après
applyavec desoutput - Connaître les quatre façons de fournir une valeur de variable et leur ordre de priorité
- Comprendre pourquoi
sensitivene protège que l'affichage, pas le stockage
Dans quel contexte ?
La configuration Terraform de l'équipe fonctionne (leçons précédentes), mais tout est codé en dur : le type d'instance, la région, le mot de passe de la base de données. Il faut désormais rendre cette configuration réutilisable pour différents environnements, sans dupliquer les fichiers .tf à chaque changement de paramètre.
D'abord, il faut déclarer une variable simple
Une variable Terraform se déclare dans un bloc variable "nom" { ... }, avec idéalement un type explicite et une description. Elle se référence ensuite partout ailleurs dans le code avec le préfixe var. (var.region).
Sans valeur par défaut (default), Terraform exige que la valeur soit fournie explicitement à chaque exécution — un choix volontaire et important pour les secrets, comme tu le verras plus loin.
Élément du bloc variable | Rôle |
|---|---|
type | Contraint le format accepté (string, number, list, map...) |
default | Valeur utilisée si rien n'est fourni ailleurs |
validation | Règle personnalisée rejetant une valeur invalide avant tout apply |
sensitive | Masque la valeur dans les logs/plan/apply (pas dans le state) |
Prérequis
Cette leçon suppose que tu es à l'aise avec la syntaxe de base d'un bloc resource (voir la leçon précédente) : les variables ne changent que la SOURCE des valeurs, pas la structure des ressources elles-mêmes.
Une fois une variable simple posée, il reste un problème : comment éviter une valeur invalide en amont ?
Sans contrôle, rien n'empêche quelqu'un de passer instance_type = "invalide" par erreur, ce qui échouerait seulement au moment de l'appel à l'API cloud, en pleine exécution du apply. Le bloc validation détecte ce genre d'erreur bien plus tôt, avec un message explicite, avant même de contacter le cloud.
Maintenant, une question sensible (au sens propre) : comment gérer un mot de passe ?
Piège fréquent
sensitive = true masque uniquement l'AFFICHAGE de la valeur dans les logs et la sortie de terraform plan/apply. Cette valeur reste malgré tout stockée EN CLAIR dans le fichier de state — une nuance cruciale qui sera détaillée dans la leçon dédiée à la sécurité, plus loin dans ce cours.
Il reste une question pratique : comment fournir concrètement une valeur à une variable ?
Quatre méthodes coexistent, avec un ordre de priorité précis : la ligne de commande (-var), un fichier .tfvars explicite (-var-file), une variable d'environnement préfixée TF_VAR_, et enfin terraform.tfvars, chargé automatiquement s'il existe dans le répertoire courant, sans rien à préciser.
Bonne pratique
Utilise un fichier terraform.tfvars par défaut pour le développement local, mais préfère des variables d'environnement TF_VAR_ en CI/CD pour les secrets : cela évite qu'un fichier contenant un mot de passe ne soit accidentellement committé dans Git.
Le lien vers la suite
Une fois une ressource créée avec des variables, il faut souvent récupérer une information calculée après coup — une adresse IP publique, un identifiant généré par le cloud. C'est exactement le rôle des output, dont tu maîtrises maintenant l'usage de base. La prochaine leçon aborde un concept fondamental encore non expliqué : le state Terraform, la mémoire de ce que l'outil a réellement créé.
Commandes & code
Variables et outputs
# variables.tf : déclare les entrées paramétrables de la configuration
variable "region" {
description = "Région AWS de déploiement"
type = string
default = "eu-west-3"
}
variable "instance_type" {
description = "Type d'instance EC2"
type = string
default = "t3.micro"
validation {
condition = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
error_message = "instance_type doit être t3.micro, t3.small ou t3.medium."
}
}
variable "tags" {
description = "Tags communs à appliquer"
type = map(string)
default = {}
}
variable "sensitive_db_password" {
description = "Mot de passe de la base"
type = string
sensitive = true # masqué dans les logs/plan/apply
}
variable "azs" {
description = "Liste des zones de disponibilité"
type = list(string)
default = ["eu-west-3a", "eu-west-3b"]
}# Utilisation des variables dans les ressources (préfixe var.)
provider "aws" {
region = var.region
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
tags = var.tags
}# outputs.tf : expose des valeurs après apply (consultables, ou utilisées par d'autres configs)
output "instance_id" {
value = aws_instance.web.id
description = "ID de l'instance EC2 créée"
}
output "instance_ip" {
value = aws_instance.web.public_ip
}
output "db_password" {
value = var.sensitive_db_password
sensitive = true # masque la valeur dans "terraform apply"
}# Fournir des valeurs de variables : 4 méthodes, par ordre de priorité croissante
terraform apply -var="region=us-east-1" # 1. ligne de commande
terraform apply -var-file="prod.tfvars" # 2. fichier .tfvars explicite
export TF_VAR_region="us-east-1" # 3. variable d'environnement (préfixe TF_VAR_)
# 4. terraform.tfvars (chargé automatiquement s'il existe dans le répertoire)
# Afficher les outputs après apply
terraform output
terraform output instance_ip # un seul output
terraform output -json # format machine-readableRésumé
variabledéclare une entrée typée (avecdefault,validation,sensitiveoptionnels) ;var.nomla référence.outputexpose une valeur consultable aprèsapply, ou consommable par une autre configuration (state distant).sensitive = truemasque une valeur dans les logs Terraform, mais elle reste en clair dans le fichier state.
Exercices pratiques
Mission : arbitrer un conflit de valeurs de variable
Objectif : Déterminer quelle source de variable l'emporte réellement et sécuriser correctement un mot de passe sensible.
Contexte
Un déploiement fournit -var="instance_type=t3.large" en ligne de commande, alors qu'un fichier terraform.tfvars présent dans le même dossier contient instance_type = "t3.micro". Par ailleurs, la variable sensitive_db_password n'a pas de default et doit être fournie sans jamais transiter par un fichier versionné dans Git.