Terraform Stacks
Terraform Stacks simplifient le provisionnement et la gestion d'infrastructure à grande échelle en fournissant une couche de configuration au-dessus des modules Terraform traditionnels. Les Stacks permettent l'orchestration déclarative de plusieurs composants dans les environnements, régions et comptes cloud.
Concepts fondamentaux
Stack : Une unité complète d'infrastructure composée de composants et de déploiements qui peuvent être gérés ensemble.
Composant : Une abstraction autour d'un module Terraform qui définit les éléments d'infrastructure. Chaque composant spécifie un module source, des entrées et des fournisseurs.
Déploiement : Une instance de tous les composants d'une Stack avec des valeurs d'entrée spécifiques. Utilisez les déploiements pour différents environnements (dev/staging/prod), régions ou comptes cloud.
Langage Stack : Un langage basé sur HCL distinct (pas le HCL Terraform standard) avec des blocs et des extensions de fichier distincts.
Structure de fichier
Terraform Stacks utilisent des extensions de fichier spécifiques :
- Configuration de composant :
.tfcomponent.hcl - Configuration de déploiement :
.tfdeploy.hcl - Fichier de verrouillage du fournisseur :
.terraform.lock.hcl(généré par la CLI)
Tous les fichiers de configuration doivent être au niveau racine du dépôt Stack. HCP Terraform traite tous les fichiers dans l'ordre des dépendances.
Organisation de fichier recommandée
my-stack/
├── .terraform-version # La version Terraform requise pour cette Stack
├── variables.tfcomponent.hcl # Déclarations de variables
├── providers.tfcomponent.hcl # Configurations des fournisseurs
├── components.tfcomponent.hcl # Définitions des composants
├── outputs.tfcomponent.hcl # Sorties de Stack
├── deployments.tfdeploy.hcl # Définitions de déploiement
├── .terraform.lock.hcl # Fichier de verrouillage du fournisseur (généré)
└── modules/ # Modules locaux (optionnel - uniquement si vous utilisez des modules locaux)
├── s3/
└── compute/
Remarque : Le répertoire modules/ est nécessaire uniquement lors de l'utilisation de sources de modules locaux. Les composants peuvent faire référence à des modules à partir de :
- Chemins de fichier locaux :
./modules/vpc - Registre public :
terraform-aws-modules/vpc/aws - Registre privé :
app.terraform.io/<org-name>/vpc/aws - Git :
git::https://github.com/org/repo.git//path?ref=v1.0.0
HCP Terraform traite tous les fichiers .tfcomponent.hcl et .tfdeploy.hcl dans l'ordre des dépendances.
Version Terraform requise (.terraform-version)
Utilisez Terraform v1.13.x ou ultérieur pour accéder au plugin CLI Stacks et exécuter les commandes terraform stacks CLI. Commencez par ajouter un fichier .terraform-version au répertoire racine de votre Stack pour spécifier la version Terraform requise pour votre Stack. Par exemple, le fichier suivant spécifie Terraform v1.14.5 :
1.14.5
Configuration de composant (.tfcomponent.hcl)
Bloc Variable
Déclarez les variables d'entrée pour la configuration Stack. Les variables doivent définir un champ type et ne supportent pas l'argument validation.
variable "aws_region" {
type = string
description = "AWS region for deployments"
default = "us-west-1"
}
variable "identity_token" {
type = string
description = "OIDC identity token"
ephemeral = true # Does not persist to state file
}
variable "instance_count" {
type = number
nullable = false
}
Important : Utilisez ephemeral = true pour les identifiants et jetons (jetons d'identité, clés API, mots de passe) pour les empêcher de persister dans les fichiers d'état. Utilisez stable pour les valeurs de longue durée comme les clés de licence qui doivent persister entre les exécutions.
Bloc required_providers
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5.0"
}
}
Bloc Provider
Les blocs Provider diffèrent de Terraform traditionnel :
- Supportent l'argument méta
for_each - Définissent les alias dans l'en-tête de bloc (pas en tant qu'argument)
- Acceptent la configuration via un bloc
config
Configuration de fournisseur unique :
provider "aws" "this" {
config {
region = var.aws_region
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}
Configurations de fournisseur multiples avec for_each :
provider "aws" "configurations" {
for_each = var.regions
config {
region = each.value
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}
Bonne pratique d'authentification : Utilisez l'identité de charge de travail (OIDC) comme méthode d'authentification préférée pour les Stacks. Cette approche :
- Évite les identifiants statiques de longue durée
- Fournit des identifiants temporaires et délimités par déploiement
- S'intègre avec IAM du fournisseur cloud (AWS IAM Roles, Azure Managed Identities, GCP Service Accounts)
- Élimine le besoin de variables d'environnement gérées par la plateforme
Configurez l'identité de charge de travail en utilisant les blocs identity_token et assume_role_with_web_identity dans la configuration du fournisseur. Pour des instructions de configuration détaillées pour AWS, Azure et GCP, voir : https://developer.hashicorp.com/terraform/cloud-docs/dynamic-provider-credentials
Bloc Component
Chaque Stack nécessite au moins un bloc component. Ajoutez un composant pour chaque module à inclure dans la Stack. Les composants référencent les modules à partir de chemins locaux, de registres ou de Git.
component "vpc" {
source = "app.terraform.io/my-org/vpc/aws" # Local, registry, or Git URL
version = "2.1.0" # For registry modules
inputs = {
cidr_block = var.vpc_cidr
name_prefix = var.name_prefix
}
providers = {
aws = provider.aws.this
}
}
Voir references/component-blocks.md pour des exemples de dépendances, for_each, modules de registre public, sources Git, et plus.
Points clés :
- Références de sortie :
component.<name>.<output>oucomponent.<name>[key].<output>pour for_each - Dépendances déduites automatiquement à partir des références de composants
- Agrégation avec les expressions for :
[for x in component.s3 : x.bucket_name] - Pour les composants avec
for_each, référencez les instances spécifiques :component.<name>[each.value].<output> - Les références de fournisseur sont des valeurs normales :
provider.<type>.<alias>ouprovider.<type>.<alias>[each.value]
Bloc Output
Les sorties nécessitent un argument type et ne supportent pas les preconditions :
output "vpc_id" {
type = string
description = "VPC ID"
value = component.vpc.vpc_id
}
output "endpoint_urls" {
type = map(string)
value = {
for region, comp in component.api : region => comp.endpoint_url
}
sensitive = false
}
Bloc Locals
Les blocs Locals fonctionnent de la même manière dans les fichiers .tfcomponent.hcl et .tfdeploy.hcl :
locals {
common_tags = {
Environment = var.environment
ManagedBy = "Terraform Stacks"
Project = var.project_name
}
region_config = {
for region in var.regions : region => {
name_suffix = "${var.environment}-${region}"
}
}
}
Bloc Removed
Utilisez pour supprimer en toute sécurité des composants d'une Stack. HCP Terraform nécessite les fournisseurs du composant pour le supprimer.
removed {
from = component.old_component
source = "./modules/old-module"
providers = {
aws = provider.aws.this
}
}
Configuration de déploiement (.tfdeploy.hcl)
Bloc Identity Token
Générez les jetons JWT pour l'authentification OIDC avec les fournisseurs cloud :
identity_token "aws" {
audience = ["aws.workload.identity"]
}
identity_token "azure" {
audience = ["api://AzureADTokenExchange"]
}
Référencez les jetons dans les déploiements en utilisant identity_token.<name>.jwt
Bloc Store
Accédez aux ensembles de variables HCP Terraform dans les déploiements Stack :
store "varset" "aws_credentials" {
id = "varset-ABC123" # Alternatively use: name = "varset_name"
source = "tfc-cloud-shared"
category = "terraform" # Alternatively use: category = "env" for environment variables
}
deployment "production" {
inputs = {
aws_access_key = store.varset.aws_credentials.AWS_ACCESS_KEY_ID
}
}
Utilisez pour centraliser les identifiants et partager les variables entre les Stacks. Voir references/deployment-blocks.md pour les détails.
Bloc Deployment
Définissez les instances de déploiement (minimum 1, maximum 20 par Stack) :
deployment "production" {
inputs = {
aws_region = "us-west-1"
instance_count = 3
role_arn = local.role_arn
identity_token = identity_token.aws.jwt
}
}
# Create multiple deployments for different environments
deployment "development" {
inputs = {
aws_region = "us-east-1"
instance_count = 1
name_suffix = "dev"
role_arn = local.role_arn
identity_token = identity_token.aws.jwt
}
}
Pour détruire un déploiement : Définissez destroy = true, téléchargez la configuration, approuvez la destruction, puis supprimez le bloc de déploiement. Voir references/deployment-blocks.md pour les détails.
Bloc Deployment Group
Regroupez les déploiements pour des paramètres partagés (fonctionnalité de niveau HCP Terraform Premium). Les niveaux Free/Standard utilisent des groupes par défaut nommés {deployment-name}_default.
deployment_group "canary" {
auto_approve_checks = [deployment_auto_approve.safe_changes]
}
deployment "dev" {
inputs = { /* ... */ }
deployment_group = deployment_group.canary
}
Plusieurs déploiements peuvent référencer le même groupe. Voir references/deployment-blocks.md pour les détails.
Bloc Deployment Auto-Approve
Définissez les règles pour approuver automatiquement les plans de déploiement (fonctionnalité de niveau HCP Terraform Premium) :
deployment_auto_approve "safe_changes" {
deployment_group = deployment_group.canary
check {
condition = context.plan.changes.remove == 0
reason = "Cannot auto-approve plans with resource deletions"
}
}
Variables de contexte disponibles : context.plan.applyable, context.plan.changes.add/change/remove/total, context.success
Remarque : Les blocs orchestrate sont obsolètes. Utilisez plutôt deployment_group et deployment_auto_approve.
Voir references/deployment-blocks.md pour toutes les variables de contexte et les modèles.
Blocs Publish Output et Upstream Input
Liez les Stacks ensemble en publiant les sorties d'une Stack et en les consommant dans une autre :
# In network Stack - publish outputs
publish_output "vpc_id_network" {
type = string
value = deployment.network.vpc_id
}
# In application Stack - consume outputs
upstream_input "network_stack" {
type = "stack"
source = "app.terraform.io/my-org/my-project/networking-stack"
}
deployment "app" {
inputs = {
vpc_id = upstream_input.network_stack.vpc_id_network
}
}
Voir references/linked-stacks.md pour la documentation complète et les exemples.
Terraform Stacks CLI
Remarque : Terraform Stacks est en disponibilité générale (GA) depuis Terraform CLI v1.13+. Les Stacks comptent maintenant pour les ressources sous gestion (RUM) pour la facturation HCP Terraform.
Initialiser et valider
terraform stacks init # Download providers, modules, generate lock file
terraform stacks providers-lock # Regenerate lock file (add platforms if needed)
terraform stacks validate # Check syntax without uploading
Workflow de déploiement
Important : Aucune commande plan ou apply. Le téléchargement de la configuration déclenche automatiquement les exécutions de déploiement.
# 1. Upload configuration (triggers deployment runs)
terraform stacks configuration upload
# 2. Monitor deployments
terraform stacks deployment-run list # List runs (non-interactive)
terraform stacks deployment-group watch -deployment-group=... # Stream status updates
# 3. Approve deployments (if auto-approve not configured)
terraform stacks deployment-run approve-all-plans -deployment-run-id=...
terraform stacks deployment-group approve-all-plans -deployment-group=...
terraform stacks deployment-run cancel -deployment-run-id=... # Cancel if needed
Gestion de la configuration
terraform stacks configuration list # List configuration versions
terraform stacks configuration fetch -configuration-id=... # Download configuration
terraform stacks configuration watch # Monitor upload status
Autres commandes
terraform stacks create # Create new Stack (interactive)
terraform stacks fmt # Format Stack files
terraform stacks list # Show all Stacks
terraform stacks version # Display version
terraform stacks deployment-group rerun -deployment-group=... # Rerun deployment
Monitoring des déploiements avec l'API HCP Terraform
Pour le monitoring programmatique dans l'automatisation, CI/CD ou les environnements non interactifs (comme les agents IA), utilisez l'API HCP Terraform au lieu des commandes CLI watch. L'API fournit des endpoints pour :
- Statut et validation de la configuration
- Résumés des groupes de déploiement
- Statut des exécutions de déploiement
- Détails des étapes de déploiement (plan/apply)
- Diagnostics d'erreur avec emplacements de fichier et extraits de code
- Sorties Stack via endpoint d'artefacts
Points clés :
- Les commandes CLI watch font du streaming indéfiniment et ne fonctionnent pas dans l'automatisation
- Utilisez l'endpoint d'artefacts pour récupérer les sorties Stack :
GET /api/v2/stack-deployment-steps/{step-id}/artifacts?name=apply-description - L'endpoint diagnostics nécessite le paramètre de requête
stack_deployment_step_id - L'endpoint d'artefacts retourne une redirection HTTP 307 (utilisez
curl -L)
Pour le workflow API complet, l'authentification, les meilleures pratiques de polling et les exemples de scripts, voir references/api-monitoring.md.
Modèles courants
Dépendances de composants : Les dépendances sont automatiquement déduites quand un composant référence la sortie d'un autre (par ex. subnet_ids = component.vpc.private_subnet_ids).
Déploiement multi-régions : Utilisez for_each sur les fournisseurs et les composants pour déployer sur plusieurs régions. Chaque région obtient sa propre configuration de fournisseur et ses instances de composants.
Modifications différées : Les Stacks supportent les modifications différées pour gérer les dépendances où les valeurs ne sont connues qu'après l'apply. Cela permet les déploiements complexes multi-composants où certaines ressources dépendent de valeurs d'exécution d'autres composants (endpoints de cluster, mots de passe générés, etc.).
Pour les exemples complets incluant les déploiements multi-régions, les dépendances de composants, les modèles de modifications différées et les Stacks liées, voir references/examples.md.
Bonnes pratiques
- Granularité des composants : Créez des composants pour les unités d'infrastructure logiques qui partagent un cycle de vie
- Compatibilité des modules :
- Les modules utilisés avec les Stacks ne peuvent pas inclure de blocs provider (configurez les fournisseurs dans la configuration Stack)
- Testez les modules du registre public avant de les utiliser dans les Stacks de production - certains modules peuvent avoir des problèmes de compatibilité
- Envisagez d'utiliser des ressources brutes pour l'infrastructure critique si la compatibilité des modules est incertaine
- Exemple : Certaines versions de terraform-aws-modules ont été trouvées avec des problèmes de compatibilité avec les Stacks (par ex. modules ALB et ECS)
- Isolation d'état : Chaque déploiement a son propre état isolé
- Variables d'entrée : Utilisez les variables pour les valeurs qui diffèrent entre les déploiements ; utilisez les locals pour les valeurs partagées
- Fichiers de verrouillage du fournisseur : Générez toujours et committez
.terraform.lock.hclau contrôle de version - Conventions de nommage : Utilisez des noms descriptifs pour les composants et les déploiements
- Groupes de déploiement : Vous pouvez organiser les déploiements en groupes de déploiement. Les groupes de déploiement permettent les règles d'approbation automatique, l'organisation logique et fournissent une base pour la scalabilité. Les groupes de déploiement sont une fonctionnalité de niveau HCP Terraform Premium
- Tests : Testez les configurations Stack dans les déploiements dev/staging avant la production
Dépannage
Dépendances circulaires : Refactorisez pour briser les références circulaires ou utilisez des composants intermédiaires.
Destruction de déploiement : Impossible de détruire depuis l'UI. Définissez destroy = true dans le bloc de déploiement, téléchargez la configuration et HCP Terraform crée une destruction.
Diagnostics vides : Ajoutez le paramètre de requête requis stack_deployment_step_id aux requêtes de l'API diagnostics.
Compatibilité des modules : Testez les modules du registre public avant une utilisation en production. Certains modules peuvent avoir des problèmes de compatibilité avec les Stacks.
Références
Pour la documentation détaillée, voir :
references/component-blocks.md- Référence complète du bloc component avec tous les arguments et la syntaxereferences/deployment-blocks.md- Référence complète du bloc deployment avec toutes les options de configurationreferences/linked-stacks.md- Publier les sorties et les entrées upstream pour lier les Stacks ensemblereferences/examples.md- Exemples de travail complets pour les déploiements multi-régions et les dépendances de composantsreferences/api-monitoring.md- Workflow API complet pour le monitoring programmatique et l'automatisationreferences/troubleshooting.md- Guide de dépannage détaillé pour les problèmes courants et les solutions