Aller au contenu
English
English
Infrastructure as Code medium

Centraliser backend et provider avec Terragrunt

8 min de lecture

logo terragrunt

Vous en avez assez de recopier la même configuration de backend dans chaque dossier Terraform ? C'est exactement le problème que résout le bloc remote_state de Terragrunt. Ce guide vous montre comment centraliser cette configuration dans root.hcl et la tester sur un backend S3 compatible MinIO en local.

Le but n'est pas seulement de faire marcher un backend. Le but est de comprendre pourquoi cette centralisation rend un live repo plus lisible et plus facile a maintenir.

  • Comprendre le role de remote_state dans root.hcl
  • Configurer un backend S3 compatible MinIO avec Terragrunt
  • Savoir quand utiliser generate pour factoriser une configuration repetee
  • Vérifier que chaque unit a bien sa propre clé de state

Sans centralisation, chaque unit finit par redéfinir :

  • le nom du bucket ou du stockage distant ;
  • la clé de state ;
  • les options propres au backend ;
  • les exceptions liées a un endpoint compatible S3 comme MinIO.

Ce n'est pas juste long a écrire. C'est surtout fragile : une variation minime entre deux units peut produire des comportements difficiles a relire plus tard.

Pour reproduire ce scenario, partez de cette arborescence :

  • Répertoirelab-d/
    • Répertoiremodules/
      • Répertoirewrite-file/
        • main.tf
    • Répertoirelive/
      • root.hcl
      • Répertoiredev/
        • Répertoireapp/
          • terragrunt.hcl

Le dossier modules/ contient le code reutilisable. Le dossier live/ contient la racine Terragrunt et la unit qui herite du backend.

Le module utilise ici est le même que dans le premier guide. Placez-le dans modules/write-file/main.tf :

terraform {
required_version = ">= 1.6.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.5"
}
}
}
variable "filename" {
type = string
}
variable "content" {
type = string
}
resource "local_file" "this" {
filename = var.filename
content = var.content
}
output "file_path" {
value = local_file.this.filename
}
output "content" {
value = local_file.this.content
}

Voici le fichier root.hcl utilise dans cet exemple :

remote_state {
backend = "s3"
config = {
bucket = "terragrunt-state"
key = "${path_relative_to_include()}/tofu.tfstate"
region = "us-east-1"
endpoint = "http://127.0.0.1:9000"
force_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
skip_requesting_account_id = true
skip_bucket_versioning = true
skip_bucket_ssencryption = true
skip_bucket_root_access = true
skip_bucket_enforced_tls = true
disable_bucket_update = true
}
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
}
ÉlémentRolePourquoi c'est utile
backend = "s3"Choisit le type de backendMinIO est compatible avec l'API S3
key = "${path_relative_to_include()}/tofu.tfstate"Produit une clé propre a chaque unitÉvite de mélanger les states
endpointPointe vers MinIOPermet un test local sans cloud public
generateÉcrit la config backend au bon endroitÉvite de recopier un backend.tf a la main

Le point le plus important est la clé de state : path_relative_to_include() permet de construire une clé distincte en fonction du dossier du unit qui inclut root.hcl.

Une unit minimale peut ensuite simplement inclure la racine :

include "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "../../../modules/write-file"
}
inputs = {
filename = "${get_terragrunt_dir()}/remote-state.txt"
content = "hello with remote state"
}

La configuration du backend ne vit plus dans la unit elle-même. Elle est héritée depuis root.hcl.

Copiez ce contenu dans live/dev/app/terragrunt.hcl.

Si tout est en place, l'exécution confirme les points suivants :

  • le backend distant est bien initialise via Terragrunt ;
  • le state est stocke dans MinIO avec une clé construite par path_relative_to_include() ;
  • l'apply cree bien le résultat attendu ;
  • le destroy nettoie proprement l'état et les ressources.

Vous pouvez vérifier côté stockage que la clé attendue existe vraiment dans votre bucket MinIO.

Le bloc generate ne sert pas qu'au backend. Il peut aussi être utilise pour factoriser un fichier de provider ou d'autres morceaux de configuration techniques quand ils doivent être injectes avant l'exécution.

L'idée a retenir est la suivante :

  • remote_state centralise la stratégie de state ;
  • generate vous aide a écrire automatiquement une configuration repetee.

Il faut l'utiliser avec mesure. Si toute la complexité du repo finit dans un seul root.hcl, vous remplacez juste de la duplication par un gros fichier difficile a relire.

SymptômeCause probableSolution
Tous les units écrivent dans le même stateLa key est statiqueUtiliser path_relative_to_include()
Le backend S3 compatible ne répond pasendpoint ou options S3 incompatiblesVérifier endpoint, path style et options de validation
backend.tf n'est pas regenereMauvaise config generateVérifier path et if_exists
  • remote_state sert a centraliser le backend dans root.hcl.
  • path_relative_to_include() évite d'écraser le state de plusieurs units.
  • Un backend S3 compatible MinIO permet de valider ce pattern localement.
  • generate aide a produire automatiquement des fichiers repetitifs comme backend.tf.
  • La centralisation doit rester lisible, pas devenir un nouveau monolithe.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn