
Un style guide ne se relit pas, il se fait rejeter par une CI. Les noms
de fichiers ne changent rien au comportement de Terraform, donc les vérifier ne
prouve rien ; ce qui prouve, c'est le code retour de terraform fmt -check et le
JSON de terraform validate. Ce guide reprend le style guide officiel, en
corrigeant les points où la pratique courante s'écarte de la source.
Il couvre le nommage des fichiers et des ressources, l'ordre des paramètres, les
commentaires, le typage des outputs, le .gitignore, et l'outillage (fmt,
validate, TFLint, pré-commit). Les comportements cités ont été vérifiés sur
Terraform v1.15.4.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Le nommage des fichiers officiel, et ses exceptions
- Nommer une ressource, et le mythe de
this - L'ordre des ressources et des paramètres (
depends_onen dernier) - Le commentaire idiomatique, et le typage des outputs (1.15)
- Le
.gitignorequi sort le state mais garde le lock fmt,validate, TFLint et les hooks de pré-commit
Prérequis
Section intitulée « Prérequis »- Un projet Terraform initialisé (installer Terraform)
- Terraform 1.15.x, la série stable courante
Le nommage des fichiers, et ses exceptions
Section intitulée « Le nommage des fichiers, et ses exceptions »Terraform concatène tous les .tf d'un dossier : la découpe est une
convention de lisibilité, sans effet technique, à deux exceptions près. Le style
guide officiel recommande cette structure :
| Fichier | Contenu |
|---|---|
terraform.tf | le bloc terraform (required_version, required_providers) |
providers.tf | tous les blocs provider |
variables.tf | toutes les variables, en ordre alphabétique |
main.tf | ressources et data sources |
outputs.tf | tous les outputs, en ordre alphabétique |
Le nom officiel du fichier portant le bloc terraform est terraform.tf,
pas versions.tf : c'est une confusion répandue. On peut aussi séparer le
backend dans un backend.tf, et déclarer plusieurs blocs terraform.
Les deux cas où le nom a un effet : les fichiers *_override.tf (et
override.tf) sont chargés en dernier et fusionnés par-dessus le reste ; et
un dépôt de module publié doit s'appeler terraform-<PROVIDER>-<NOM>, imposé
par le registre.
Nommer une ressource : le mythe de this
Section intitulée « Nommer une ressource : le mythe de this »Une ressource se nomme avec un nom descriptif en snake_case, sans répéter le type que l'adresse porte déjà :
# bien : l'adresse est random_pet.serveurresource "random_pet" "serveur" {}
# mal : camelCase, et le nom repete le typeresource "random_pet" "randomPetServeur" {}Le nom this pour la ressource unique d'un module est une convention
communautaire répandue, mais le style guide officiel ne le mentionne
jamais : il demande seulement « a descriptive noun and separate words with
underscores ». Le présenter comme une règle officielle est un abus.
L'ordre des ressources et des paramètres
Section intitulée « L'ordre des ressources et des paramètres »Deux ordres officiels sont souvent inversés. D'abord, les ressources dépendantes se déclarent APRÈS celles qu'elles référencent (« let your code build on itself »), et une data source avant la ressource qui la consomme.
Ensuite, à l'intérieur d'un bloc resource, l'ordre officiel des paramètres est :
countoufor_each, si présent ;- les arguments non-bloc de la ressource ;
- les arguments de type bloc ;
- un bloc
lifecycle, si besoin ; depends_onen DERNIER, si besoin.
Commentaires : seul # est idiomatique
Section intitulée « Commentaires : seul # est idiomatique »HCL accepte #, // et /* */, mais la doc tranche : seul # est
idiomatique, en une ligne comme en plusieurs. « The // and /* */ comment
syntaxes are not considered idiomatic, but Terraform supports them to remain
backward-compatible with earlier versions of HCL. » Les deux autres ne survivent
que par compatibilité ascendante ; ne les recommandez pas.
Typer les variables ET les outputs
Section intitulée « Typer les variables ET les outputs »Depuis Terraform 1.15, le style guide demande un type et une
description sur chaque output, comme pour les variables. Le type n'est
pas cosmétique. Vérifié en 1.15.4 : un output type = number dont la valeur vient
d'un terraform.tfvars qui l'écrit "2" (entre guillemets) ressort en JSON avec
"type": "number", "value": 2, contre "type": "string", "value": "2" sans la
déclaration.
output "nombre_noeuds" { type = number description = "Nombre de noeuds." value = var.nombre_noeuds}L'ordre officiel des paramètres est type, description, default,
sensitive, validation pour une variable ; type, description, value,
sensitive pour un output.
Le .gitignore : le state dehors, le lock dedans
Section intitulée « Le .gitignore : le state dehors, le lock dedans »C'est la seule règle du style guide dont l'oubli a des conséquences de sécurité
immédiates. On n'committe jamais : le répertoire .terraform/, les fichiers
terraform.tfstate*, .terraform.tfstate.lock.info, les plans sauvegardés par
-out, et tout .tfvars sensible. On committe en revanche
.terraform.lock.hcl, le fichier de verrouillage des versions de providers.
.terraform/terraform.tfstateterraform.tfstate.*.terraform.tfstate.lock.info*.tfplan*.tfvars!.terraform.lock.hclfmt, validate, et le reste de l'outillage
Section intitulée « fmt, validate, et le reste de l'outillage »Deux commandes, deux rôles distincts :
terraform fmtnormalise l'indentation, aligne les=, espace les maps inline.terraform fmt -checksort en code 3 (pas 1) quand un fichier n'est pas formaté, vérifié en 1.15.4.terraform validatevérifie la cohérence interne et les types, mais ne valide pas les valeurs auprès du provider et **n'**évalue pas le state.
Terraform n'a pas de linter intégré : la doc recommande TFLint. Et le bon
endroit pour lancer fmt et validate est un hook de pré-commit Git, là où
l'erreur se corrige le moins cher, avant même la CI.
Au-delà du code : le workflow
Section intitulée « Au-delà du code : le workflow »Le style guide officiel a une seconde moitié, souvent oubliée : le workflow style. Elle couvre la structure de dépôt (un module par dépôt), la stratégie de branches, la gestion des environnements multiples, le partage de state entre configurations, les tests de modules et les politiques d'enforcement. Pour un profil Professional, cette partie recoupe directement les sous-objectifs sur le state distant et les workflows d'équipe.
Dépannage
Section intitulée « Dépannage »Ces symptômes se lisent tous avant la CI. Le tableau associe chaque écart de style à sa cause.
| Symptôme | Cause | Solution |
|---|---|---|
terraform fmt -check sort en code 3 | Un fichier n'est pas formaté | Lancer terraform fmt (idéalement en pré-commit) |
validate échoue sur une référence inconnue | Une variable ou ressource référencée mais non déclarée | Déclarer l'objet, ou corriger le nom |
.terraform.lock.hcl absent du dépôt | Ignoré par .terraform* | Ignorer le répertoire par .terraform/, garder le lock |
Un output number sort en chaîne | Pas de contrainte type | Déclarer type = number sur l'output |
Un depends_on en tête déroute la relecture | Ordre non conforme | Le placer en dernier, après lifecycle |
À retenir
Section intitulée « À retenir »- Le bloc
terraformva dansterraform.tf, pasversions.tf. - Une ressource se nomme en snake_case descriptif ;
thisest une convention communautaire, pas officielle. - Les ressources dépendantes se déclarent après leurs références ;
depends_onen dernier dans un bloc. - Seul
#est un commentaire idiomatique. - Depuis 1.15, typez les outputs comme les variables.
- Le
.gitignoresort le state mais garde.terraform.lock.hcl; gare à.terraform*. fmtformate,validatevérifie les types (pas les valeurs provider), TFLint lint, le pré-commit automatise.
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »Les questions ci-dessous reprennent les confusions les plus fréquentes du style
guide : le nom du fichier terraform, la place de depends_on, et le
.gitignore.
Le nom officiel est terraform.tf
Le style guide dit : « Aterraform.tf file that contains a single terraform block which defines your required_version and required_providers. »Le nom versions.tf est répandu mais n'apparaît nulle part dans la source officielle.À noter
On peut séparer le backend dans unbackend.tf, et déclarer plusieurs blocs terraform pour isoler le backend du versionnage.L'ordre officiel
countoufor_each- les arguments non-bloc
- les arguments de type bloc
- un bloc
lifecycle depends_onen dernier
L'erreur fréquente
Beaucoup de guides rangentdepends_on avec count/for_each au sommet du bloc. C'est faux : depends_on est le dernier paramètre, après lifecycle.Le lock se committe
.terraform.lock.hcl verrouille les versions de providers et se versionne : il appartient à la configuration.Ce qu'on ignore
.terraform/, terraform.tfstate*, .terraform.tfstate.lock.info, les plans -out, les .tfvars sensibles.Le piège .terraform*
.terraform/ # correct : le repertoire seul
!.terraform.lock.hcl # explicite
Écrire .terraform* (avec l'étoile) ignorerait aussi le lock. Le slash final restreint le motif au répertoire.Une nouveauté 1.15
Le style guide demande désormais untype et une description sur chaque output, comme pour les variables.Le type n'est pas cosmétique
Vérifié en 1.15.4 : un outputtype = number dont la valeur vient d'un terraform.tfvars qui l'écrit "2" ressort en JSON avec "type": "number", "value": 2, contre "value": "2" sans la déclaration.output "nombre_noeuds" {
type = number
description = "Nombre de noeuds."
value = var.nombre_noeuds
}
Seul # est idiomatique
« Use# for both single- and multi-line comments. The // and /* */ comment syntaxes are not considered idiomatic, but Terraform supports them to remain backward-compatible with earlier versions of HCL. »Conséquence
Même pour un commentaire sur plusieurs lignes, on empile des#, pas un bloc /* */. Recommander /* */ comme style multi-ligne va contre la source officielle.Deux rôles distincts
terraform fmt: normalise l'indentation, aligne les=, espace les maps.fmt -checksort en code 3 quand un fichier n'est pas formaté (vérifié en 1.15.4).terraform validate: vérifie la cohérence interne et les types.
Ce que validate ne fait PAS
« Thevalidate command does not check if argument values are valid for a specific provider, but it will verify that they are the correct type. It does not evaluate any existing state. » Pour aller plus loin, la doc recommande TFLint.Une convention, pas une règle
Le style guide officiel ne mentionne jamaisthis. Il dit seulement : « use a descriptive noun and separate words with underscores ».D'où vient this
C'est une convention communautaire répandue, notamment dans les modulesterraform-aws-modules, pour la ressource unique d'un module. Utile, mais elle n'a pas l'autorité de la source officielle : ne la présentez pas comme telle.Pour aller plus loin
Section intitulée « Pour aller plus loin »- Les ressources éphémères : Une bonne pratique de plus : garder hors du state ce qui n'a pas à y figurer.
- Quiz Écrire du code Terraform : Un contrôle des acquis sur l'ensemble des règles d'écriture de la section.
- Organiser un dépôt Terraform : Le prolongement du style guide à l'échelle du dépôt entier, pas du seul fichier.