Structurer un projet Terraform
La structure d'un projet Terraform conditionne sa maintenabilité sur le long terme. Un projet flat avec tout dans un seul répertoire fonctionne pour un POC. Pour une infrastructure production avec plusieurs environnements et plusieurs équipes, une structure réfléchie évite les catastrophes.
Structure flat : pour les projets simples
projet-simple/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── versions.tf
├── terraform.tfvars
└── .terraform.lock.hclConvient pour : un seul environnement, une petite infrastructure, un POC.
Structure par environnement : la plus courante
infrastructure/
├── modules/
│ ├── vpc/
│ ├── ec2/
│ └── rds/
├── environments/
│ ├── prod/
│ │ ├── main.tf # appelle les modules
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ ├── backend.tf # config backend S3 prod
│ │ └── terraform.tfvars
│ ├── staging/
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ └── dev/
│ └── ...
└── README.mdChaque environnement a son propre state, son propre backend, et ses propres accès. C'est la structure recommandée pour les équipes.
backend.tf par environnement
# environments/prod/backend.tf
terraform {
backend "s3" {
bucket = "mon-bucket-tfstate"
key = "prod/terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}.gitignore
# State files — jamais dans Git
*.tfstate
*.tfstate.backup
.terraform/
# Variables avec secrets
*.tfvars
!example.tfvars # conserver un exemple sans secrets
# Plans binaires
*.tfplan
# Overrides locaux
override.tf
override.tf.json
*_override.tfexample.tfvars : documentation des variables requises
# terraform.tfvars.example — versionné dans Git
# Copier en terraform.tfvars et remplir les valeurs
aws_region = "eu-west-1"
environment = "prod"
project_name = "monprojet"
# Secrets — récupérer depuis le gestionnaire de secrets
db_password = "CHANGER_MOI"
api_key = "CHANGER_MOI"Conventions de nommage
Un naming cohérent simplifie la lecture des plans et des logs :
- Ressources :
snake_case, nom local descriptif (web_serverplutôt queec2) - Variables :
snake_case, préfixées par le domaine si nécessaire (db_password,vpc_cidr) - Modules :
snake_case, nom fonctionnel (module "app_vpc") - Resources AWS :
kebab-casedans les tagsName, préfixé par l'environnement (prod-web-01)