terraform-stacks

Par hashicorp · agent-skills

Guide complet pour travailler avec HashiCorp Terraform Stacks. À utiliser lors de la création, modification ou validation de configurations Terraform Stack (fichiers `.tfcomponent.hcl`, `.tfdeploy.hcl`), pour travailler avec des composants et déploiements de stack provenant de modules locaux, du registre public ou de registres privés, pour gérer une infrastructure multi-région ou multi-environnement, ou pour résoudre des problèmes de syntaxe et de structure Terraform Stacks.

npx skills add https://github.com/hashicorp/agent-skills --skill terraform-stacks

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 :

  1. Supportent l'argument meta for_each
  2. Définissent les aliases dans l'en-tête du bloc (pas comme argument)
  3. 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> ou component.<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> ou provider.<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

  1. Component Granularity: Créez des composants pour les unités logiques d'infrastructure qui partagent un lifecycle
  2. 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)
  3. State Isolation: Chaque déploiement a son propre state isolé
  4. 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
  5. Provider Lock Files: Générez toujours et committez .terraform.lock.hcl au version control
  6. Naming Conventions: Utilisez des noms descriptifs pour les composants et les déploiements
  7. 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
  8. 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 syntaxe
  • references/deployment-blocks.md - Référence complète du bloc deployment avec toutes les options de configuration
  • references/linked-stacks.md - Publish outputs et upstream inputs pour lier les Stacks ensemble
  • references/examples.md - Exemples complets et fonctionnels pour les déploiements multi-régions et les dépendances de composants
  • references/api-monitoring.md - Workflow complet de l'API pour la surveillance programmatique et l'automation
  • references/troubleshooting.md - Guide de dépannage détaillé pour les problèmes courants et les solutions

Skills similaires