Background Image
PERSPECTIVES TECHNOLOGIQUES

Environnements multiples avec Terraform

Headshot - Paul Hassinger
Paul Hassinger
Consultant principal

June 13, 2025 | 6 Lecture minute

Configurations DRY IaC

Terraform est un outil fantastique pour créer des solutions d'Infrastructure as Code (IaC). Les configurations DRY (Don't Repeat Yourself) sont idéales pour éviter la duplication des paramètres de configuration en les centralisant. Il existe des approches de configuration DRY Terraform communes et standardisées dans l'industrie, mais de nombreuses options présentent des inconvénients qui les rendent moins souhaitables. Je partage avec vous une solution DRY IaC que j'utilise et qui répond à la plupart de ces problèmes grâce à l'utilisation de Terragrunt pour combiner plusieurs approches.

Espaces de travail Terraform

Terraform espaces de travail permettent de stocker indépendamment l'état d'un environnement pour une configuration IaC unique. Sur sa page consacrée aux espaces de travail, Hashicorp indique : "Les espaces de travail ne conviennent pas à la décomposition des systèmes ou aux déploiements nécessitant des identifiants et des contrôles d'accès distincts. Se référer auxCas d'utilisationdans la documentation Terraform CLI pour plus de détails et les alternatives recommandées". La page des cas d'utilisation indique clairement qu'il existe de nombreuses limitations et qu'il n'est pas recommandé d'isoler les environnements.

Les espaces de travail Terraform de HCP répondent à certains des problèmes, mais nécessitent l'utilisation de sa plateforme cloud et séparent essentiellement ces espaces de travail dans leur propre configuration indépendante, ce qui laisse beaucoup de place à la dérive et à la duplication du code.

Modules Terraform

Une des meilleures pratiques de l'industrie pour obtenir des configurations DRY est d'utiliser des modules Terraform. En utilisant ces modules avec des variables différentes, le code IaC peut appeler le module à plusieurs reprises pour différents environnements. Les paramètres qui ne changent pas restent ainsi globaux, à l'intérieur du module. Les paramètres dynamiques sont conservés en dehors du module dans le code appelant.

Cette approche pose toutefois plusieurs problèmes. En particulier, la configuration du backend doit être répétée et les configurations d'environnement disjointes doivent être mises à jour indépendamment, ce qui peut entraîner une dérive dans les configurations stockées qui sont utilisées.

Terragrunt

Terragrunt a été conçu pour résoudre un grand nombre des problèmes nécessaires à l'obtention de configurations DRY Terraform IaC. L'utilisation de Terragrunt est controversée par certains ingénieurs de l'industrie, mais je crois que beaucoup de ces arguments sont erronés et dans certains cas où ils sont valables, les avantages DRY de l'utilisation de Terragrunt l'emportent souvent sur ces points. C'est particulièrement vrai lorsque la taille et la maintenabilité des configurations IaC deviennent difficiles à gérer, mais cela peut également présenter des avantages pour des cas d'utilisation plus restreints.

L'utilisation de Terragrunt permet de résoudre les problèmes de code IaC DRY de Terraform de plusieurs façons. Les configurations dynamiques peuvent être centralisées pour les entrées, les modules, les fournisseurs et les backends d'état. De plus, le code IaC peut inclure d'autres codes IaC sans avoir à créer un module complètement séparé.

Même en utilisant du code ou des paramètres partagés (que je qualifierai de globaux), nous pouvons concevoir notre solution de manière à pouvoir compléter ce code ou à le remplacer complètement. En plus de remplacer les variables, nous pouvons également inclure des modules avec des versions différentes si nous le souhaitons. Cela peut s'avérer particulièrement important si vous disposez d'un environnement "bac à sable" dans lequel vous souhaitez tester une nouvelle version d'un module ou de paramètres sans affecter d'autres environnements à l'aide de votre configuration globale. Développez ces types de personnalisation dans votre système CICD et le code devient alors gérable au lieu d'être une toile d'araignée de code dupliqué à maintenir.

Solution DRY Terragrunt

Construisons la structure d'un exemple de projet qui transmet des ACL et un nom de domaine à un module.

Structure du projet

Nous obtiendrons la structure de projet suivante :

projet-environnements-multiples

├── dev

│ ├── acls.tf

│ ├─── environment.auto.tfvars

│ ├─── terragrunt.hcl

│ └─── variables.tf

├── global

│ ├── global-acls.tf

│ ├─── global-main.tf

├─── prod

│ ├── acls.tf

│ ├─── environment.auto.tfvars

│ ├─── terragrunt.hcl

│ └─── variables.tf

└── terragrunt-root.hcl

terragrunt-root.hcl

Ce fichier est utilisé pour les paramètres partagés du projet racine. Typiquement, cela inclurait des paramètres d'état à distance ou des configurations de fournisseurs. Pour cette démonstration, l'état n'est pas nécessaire, il peut donc s'agir d'un fichier vide.

locals { 
  environment_remote_backend = get_env("REMOTE_STATE_CREDENTIALS", "") != "" ? "remote_state_tbd" : "local" 
} 
generate "backend" { 
  path      = "backend.tf" 
  if_exists = "overwrite_terragrunt" 
  contents  = <<EOF 
terraform { 
  %{if local.environment_remote_backend == "local"} 
  backend "local" { 
    path   = "terraform.tfstate" 
  } 
  %{else} 
  backend "remote_state_tbd" { 
    bucket = "myproject-tfstate-${basename(get_terragrunt_dir())}" 
  } 
  %{endif} 
} 
  EOF 
} 

terragrunt.hcl

Ce fichier est utilisé dans chaque répertoire d'environnement pour hériter des paramètres racine de terragrunt. Nous l'utilisons également pour inclure du code global.

terraform { 

  source = "${get_terragrunt_dir()}/../global" 

} 

 

include "root" { 

  path = find_in_parent_folders("terragrunt-root.hcl") 

} 

variables.tf

Ce fichier est utilisé dans chaque répertoire d'environnement pour définir des variables environnementales qui peuvent être dynamiques par environnement, ou des informations d'identification à transmettre au module.

variable "environment_name" { 

  description = "Environment Name" 

  type        = string 

} 

environnement.auto.tfvars

Ce fichier est utilisé dans chaque répertoire d'environnement pour définir les tfvars de l'environnement. Il peut s'agir du nom d'un environnement.

environment_name = "dev|prod" 

global-main.tf

Ce fichier est utilisé pour appeler globalement le module principal pour tous les environnements. Cette même fonctionnalité pourrait être placée dans chaque environnement, mais en la gardant dans le répertoire global, elle sera automatiquement utilisée par les environnements. Le module utilise une entrée pour les ACL des ACL locales définies pour chaque environnement.

module "my_reusable_module" { 

  source               = "path-to-my-module" 

  domain               = var.environment_name 

  acls                 = local.acls 

} 

global-acls.tf

Ce fichier est utilisé pour définir globalement les ACL à utiliser pour tout environnement qui le souhaite.

locals { 

  global_myobjects = [ 

    { 

      name = "Home" 

      entries = [ 

        { ip = "192.168.1.1" }, 

        { ip = "192.168.1.2" }, 

      ] 

    }, 

    { 

      name = "Office" 

      entries = [ 

        { ip = "192.168.2.1" }, 

        { ip = "192.168.2.2" }, 

      ] 

    }, 

  ] 

}

acls.tf

Ce fichier est utilisé dans chaque répertoire d'environnement pour définir une variable ACL locale. Dans l'exemple prod, nous utilisons simplement ce qui se trouve dans les ACL globales. Pour dev, nous ajoutons une troisième ACL que nous souhaitons tester, en plus des ACL globales.

Prod :

locals { 

  acls = concat( 

    local.global_acls, 

  ) 

} 

Dev :

locals { 

  acls = concat( 

    local.global_acls, 

    { 

      name = "Dev Datacenter" 

      entries = [ 

        { ip = "192.168.3.1" }, 

        { ip = "192.168.3.2" }, 

      ] 

    }, 

  ) 

}

Exécution

L'exécution du code Terraform avec Terragrunt devient un jeu d'enfant :

terragrunt init --all 

terragrunt plan --all 

terragrunt apply --all --queue-include-dir dev 

terragrunt apply --all --queue-include-dir production 

terragrunt destroy –all 

Réflexions finales

Bien qu'il existe de nombreuses solutions pour gérer plusieurs environnements avec Terraform, l'exemple fourni nous permet d'obtenir une solution Terraform IaC flexible qui fait abstraction des fonctionnalités globales pour faciliter la réutilisation et la maintenance, tout en permettant de remplacer les paramètres ou les fonctionnalités propres à chaque environnement.

La mise en œuvre de plusieurs environnements pour utiliser la configuration DRY IaC Terraform avec Terragrunt fournit un code gérable, qu'il s'agisse de quelques environnements, de plusieurs environnements ou même d'environnements éphémères. Intégrez-le pour simplifier les flux de travail CICD et laissez-le accélérer votre activité.

Ces types de solutions et de personnalisations offrent une grande flexibilité et une grande efficacité pour les besoins de votre entreprise. Pour en savoir plus sur la façon dont nos solutions personnalisées peuvent contribuer à la réussite de votre entreprise, contactez-nous!

Perspectives technologiques

Dernières réflexions

Explorez nos articles de blog et laissez-vous inspirer par les leaders d'opinion de nos entreprises.
Asset - Thumbnail - Humans, Agents, Time, and Tools: Redefining the Future of Work - AI workplace
AI

Humains, agents, temps et outils : Redéfinir l'avenir du travail

L'impact des solutions agentiques d'IA et la façon dont elles peuvent révolutionner le flux de travail de votre organisation.