Terraform Stacks
Terraform Stacks simplifie l'approvisionnement et la gestion de l'infrastructure à grande échelle en fournissant une couche de configuration au-dessus des modules Terraform traditionnels. Les Stacks permettent une orchestration déclarative de multiples composants across environments, regions, et cloud accounts.
Core Concepts
Stack: Une unité complète d'infrastructure composée de composants et de déploiements qui peuvent être gérés ensemble.
Component: Une abstraction autour d'un module Terraform qui définit des éléments d'infrastructure. Chaque composant spécifie un module source, des entrées et des providers.
Deployment: 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 cloud accounts.
Stack Language: Un langage distinct basé sur HCL (pas du HCL Terraform régulier) avec des blocs distincts et des extensions de fichiers.
File Structure
Terraform Stacks utilise des extensions de fichiers spécifiques :
- Component configuration:
.tfcomponent.hcl - Deployment configuration:
.tfdeploy.hcl - Provider lock file:
.terraform.lock.hcl(généré par 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.
Recommended File Organization
my-stack/
├── .terraform-version # The required Terraform version for this Stack
├── variables.tfcomponent.hcl # Variable declarations
├── providers.tfcomponent.hcl # Provider configurations
├── components.tfcomponent.hcl # Component definitions
├── outputs.tfcomponent.hcl # Stack outputs
├── deployments.tfdeploy.hcl # Deployment definitions
├── .terraform.lock.hcl # Provider lock file (generated)
└── modules/ # Local modules (optional - only if using local modules)
├── s3/
└── compute/
Note: Le répertoire modules/ n'est requis que lors de l'utilisation de sources de modules locales. Les composants peuvent référencer des modules depuis :
- Local file paths:
./modules/vpc - Public registry:
terraform-aws-modules/vpc/aws - Private registry:
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.
Required Terraform version (.terraform-version)
Utilisez Terraform v1.13.x ou ultérieur pour accéder au plugin Stacks CLI et exécuter les commandes terraform stacks CLI. Commencez par ajouter un fichier .terraform-version à la racine de votre répertoire 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
Component Configuration (.tfcomponent.hcl)
Variable Block
Déclarez des 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 credentials et tokens (identity tokens, API keys, passwords) pour éviter qu'ils ne persistent dans les fichiers state. Utilisez stable pour les valeurs plus durables comme les license keys qui doivent persister entre les exécutions.
Required Providers Block
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.5.0"
}
}
Provider Block
Les blocs provider diffèrent du Terraform traditionnel :
- Supportent l'argument meta
for_each - Définissent les aliases dans l'en-tête du bloc (pas comme argument)
- Acceptent la configuration via un bloc
config
Single Provider Configuration:
provider "aws" "this" {
config {
region = var.aws_region
assume_role_with_web_identity {
role_arn = var.role_arn
web_identity_token = var.identity_token
}
}
}
Multiple Provider Configurations with 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
}
}
}
Authentication Best Practice: Utilisez workload identity (OIDC) comme méthode d'authentification préférée pour les Stacks. Cette approche :
- Évite les credentials statiques de longue durée
- Fournit des credentials temporaires et scoped par exécution de déploiement
- S'intègre avec IAM des cloud providers (AWS IAM Roles, Azure Managed Identities, GCP Service Accounts)
- Élimine le besoin de variables d'environnement gérées par la plateforme
Configurez workload identity en utilisant les blocs identity_token et assume_role_with_web_identity dans la configuration du provider. Pour les instructions de configuration détaillées pour AWS, Azure et GCP, voir : https://developer.hashicorp.com/terraform/cloud-docs/dynamic-provider-credentials
Component Block
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 depuis des chemins locaux, des registries ou 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 registries publiques, sources Git et plus.
Key Points:
- Reference outputs:
component.<name>.<output>oucomponent.<name>[key].<output>pour for_each - Les dépendances sont automatiquement déduites des références de composants
- Agréger avec des 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 providers sont des valeurs normales :
provider.<type>.<alias>ouprovider.<type>.<alias>[each.value]
Output Block
Les outputs nécessitent un argument type et ne supportent pas 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
}
Locals Block
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}"
}
}
}
Removed Block
Utilisez pour supprimer en toute sécurité les composants d'une Stack. HCP Terraform nécessite les providers du composant pour le supprimer.
removed {
from = component.old_component
source = "./modules/old-module"
providers = {
aws = provider.aws.this
}
}
Deployment Configuration (.tfdeploy.hcl)
Identity Token Block
Générez des tokens JWT pour l'authentification OIDC avec les cloud providers :
identity_token "aws" {
audience = ["aws.workload.identity"]
}
identity_token "azure" {
audience = ["api://AzureADTokenExchange"]
}
Référencez les tokens dans les déploiements en utilisant identity_token.<name>.jwt
Store Block
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 credentials et partager les variables across Stacks. Voir references/deployment-blocks.md pour les détails.
Deployment Block
Définissez des 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, uploadez la configuration, approuvez la run de destruction, puis supprimez le bloc deployment. Voir references/deployment-blocks.md pour les détails.
Deployment Group Block
Groupez les déploiements ensemble pour les paramètres partagés (fonctionnalité du tier HCP Terraform Premium). Les tiers Free/standard utilisent les 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.
Deployment Auto-Approve Block
Définissez des règles pour approuver automatiquement les plans de déploiement (fonctionnalité du tier 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"
}
}
Available context variables: context.plan.applyable, context.plan.changes.add/change/remove/total, context.success
Note: Les blocs orchestrate sont dépréciés. Utilisez deployment_group et deployment_auto_approve à la place.
Voir references/deployment-blocks.md pour toutes les variables de contexte et les patterns.
Publish Output et Upstream Input Blocks
Liez les Stacks ensemble en publishant les outputs 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 des exemples.
Terraform Stacks CLI
Note: Terraform Stacks est Generally Available (GA) depuis Terraform CLI v1.13+. Les Stacks comptent maintenant vers Resources Under Management (RUM) pour la facturation HCP Terraform.
Initialize et Validate
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
Deployment Workflow
Important: Pas de commandes plan ou apply. L'upload de la configuration déclenche automatiquement les deployment runs.
# 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
Configuration Management
terraform stacks configuration list # List configuration versions
terraform stacks configuration fetch -configuration-id=... # Download configuration
terraform stacks configuration watch # Monitor upload status
Other Commands
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 Deployments with HCP Terraform API
Pour une surveillance programmatique en automation, CI/CD, ou environnements non-interactifs (comme les agents IA), utilisez l'API HCP Terraform à la place des commandes CLI watch. L'API fournit des endpoints pour :
- Configuration status et validation
- Deployment group summaries
- Deployment run status
- Deployment step details (plan/apply)
- Error diagnostics avec file locations et code snippets
- Stack outputs via artifacts endpoint
Key points:
- Les commandes CLI watch streams indéfiniment et ne fonctionnent pas en automation
- Utilisez l'artifacts endpoint pour récupérer les Stack outputs :
GET /api/v2/stack-deployment-steps/{step-id}/artifacts?name=apply-description - L'endpoint diagnostics nécessite le paramètre query
stack_deployment_step_id - L'artifacts endpoint retourne une redirection HTTP 307 (utilisez
curl -L)
Pour le workflow complet de l'API, l'authentification, les best practices de polling et les scripts d'exemple, voir references/api-monitoring.md.
Common Patterns
Component Dependencies: Les dépendances sont automatiquement déduites quand un composant référence l'output d'un autre (par exemple, subnet_ids = component.vpc.private_subnet_ids).
Multi-Region Deployment: Utilisez for_each sur les providers et les composants pour déployer across multiple regions. Chaque région obtient sa propre configuration de provider et instances de composants.
Deferred Changes: Les Stacks supportent les deferred changes pour gérer les dépendances où les valeurs ne sont connues qu'après l'apply. Cela permet des déploiements multi-composants complexes où certaines ressources dépendent des valeurs runtime d'autres composants (cluster endpoints, generated passwords, etc.).
Pour des exemples complets incluant des déploiements multi-régions, les dépendances de composants, les patterns deferred changes et les Stacks liées, voir references/examples.md.
Best Practices
- Component Granularity: Créez des composants pour les unités logiques d'infrastructure qui partagent un lifecycle
- Module Compatibility:
- Les modules utilisés avec Stacks ne peuvent pas inclure de blocs provider (configurez les providers dans la configuration Stack)
- Testez les modules de registries publiques avant de les utiliser en production dans des Stacks - certains modules peuvent avoir des problèmes de compatibilité
- Considérez l'utilisation de raw resources pour l'infrastructure critique si la compatibilité du module est incertaine
- Exemple : Certaines versions de terraform-aws-modules ont été trouvées avec des problèmes de compatibilité avec les Stacks (par exemple, les modules ALB et ECS)
- State Isolation: Chaque déploiement a son propre state isolé
- Input Variables: Utilisez les variables pour les valeurs qui diffèrent d'un déploiement à l'autre ; utilisez les locals pour les valeurs partagées
- Provider Lock Files: Générez toujours et committez
.terraform.lock.hclau version control - Naming Conventions: Utilisez des noms descriptifs pour les composants et les déploiements
- Deployment Groups: Vous pouvez organiser les déploiements dans des deployment groups. Les deployment groups permettent les règles d'auto-approbation, l'organisation logique et fournissent une base pour la scalabilité. Les deployment groups sont une fonctionnalité du tier HCP Terraform Premium
- Testing: Testez les configurations Stack dans les déploiements dev/staging avant la production
Troubleshooting
Circular Dependencies: Refactorisez pour briser les références circulaires ou utilisez des composants intermédiaires.
Deployment Destruction: Impossible de détruire depuis l'UI. Définissez destroy = true dans le bloc deployment, uploadez la configuration, et HCP Terraform crée une destroy run.
Empty Diagnostics: Ajoutez le paramètre query stack_deployment_step_id requis aux demandes d'API diagnostics.
Module Compatibility: Testez les modules de registries publiques avant l'utilisation en production. Certains modules peuvent avoir des problèmes de compatibilité avec les Stacks.
References
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- Publish outputs et upstream inputs pour lier les Stacks ensemblereferences/examples.md- Exemples complets et fonctionnels pour les déploiements multi-régions et les dépendances de composantsreferences/api-monitoring.md- Workflow complet de l'API pour la surveillance programmatique et l'automationreferences/troubleshooting.md- Guide de dépannage détaillé pour les problèmes courants et les solutions