mcpField
T
terraform-stacks

terraform-stacks

github.com/hashicorpクラウド・DevOps9095.6k 回インストール今日更新
リポジトリ

terraform-stacks について

Terraform StacksでTerraformのコンポーネントとデプロイを環境、リージョン、クラウドアカウント間で編成するためのガイドです。大規模なインフラを管理するチーム向けに、専用の設定言語、CLIの手順、HCP Terraform APIによる監視を扱います。

主な機能

  1. 01モジュールをStackコンポーネントとして構成
  2. 02環境やリージョンごとのデプロイ定義
  3. 03OIDCワークロードアイデンティティ認証
  4. 04Stacks CLIで設定とデプロイを管理
  5. 05HCP Terraform APIで実行を監視

活用シーン

  1. 01複数環境にインフラモジュールを編成
  2. 02リージョンやクラウドアカウント間でコンポーネントをデプロイ
  3. 03自動化処理でデプロイ状況を監視

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/terraform-stacksを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
api-monitoring.md
component-blocks.md
deployment-blocks.md
examples.md
linked-stacks.md
troubleshooting.md

詳細

Terraform Stacks

Terraform Stacks は、従来の Terraform モジュールの上位に構成レイヤーを提供することで、大規模なインフラストラクチャのプロビジョニングと管理を簡素化します。Stacks を使うと、環境、リージョン、クラウドアカウントにまたがる複数のコンポーネントを宣言的にオーケストレーションできます。

コアコンセプト

Stack:コンポーネントとデプロイメントで構成され、まとめて管理できるインフラストラクチャの完全な単位です。

コンポーネント:インフラストラクチャの要素を定義する Terraform モジュールの抽象化です。各コンポーネントでは、ソースモジュール、入力値、プロバイダーを指定します。

デプロイメント:特定の入力値を使用する、Stack 内のすべてのコンポーネントのインスタンスです。異なる環境(dev/staging/prod)、リージョン、またはクラウドアカウントには、デプロイメントを使用します。

Stack 言語:独自のブロックとファイル拡張子を持つ、別個の HCL ベースの言語です(通常の Terraform HCL ではありません)。

ファイル構成

Terraform Stacks では、専用のファイル拡張子を使用します。

  • コンポーネント構成:.tfcomponent.hcl
  • デプロイメント構成:.tfdeploy.hcl
  • プロバイダーのロックファイル:.terraform.lock.hcl(CLI によって生成)

すべての構成ファイルは、Stack リポジトリのルートレベルに配置する必要があります。HCP Terraform は、依存関係の順序に従ってすべてのファイルを処理します。

推奨されるファイル構成
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/

注:modules/ ディレクトリが必要なのは、ローカルモジュールソースを使用する場合のみです。コンポーネントでは、次の場所にあるモジュールを参照できます。

  • ローカルファイルパス:./modules/vpc
  • パブリックレジストリ:terraform-aws-modules/vpc/aws
  • プライベートレジストリ:app.terraform.io/<org-name>/vpc/aws
  • Git:git::https://github.com/org/repo.git//path?ref=v1.0.0

HCP Terraform は、すべての .tfcomponent.hcl ファイルと .tfdeploy.hcl ファイルを依存関係の順序に従って処理します。

必要な Terraform バージョン(.terraform-version)

Stacks CLI プラグインにアクセスし、terraform stacks CLI コマンドを実行するには、Terraform v1.13.x 以降を使用してください。まず、Stack のルートディレクトリに .terraform-version ファイルを追加し、Stack に必要な Terraform のバージョンを指定します。たとえば、次のファイルは Terraform v1.14.5 を指定します。

1.14.5

コンポーネント構成(.tfcomponent.hcl)

Variable ブロック

Stack 構成の入力変数を宣言します。変数には type フィールドを定義する必要があり、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
}

重要:認証情報やトークン(ID トークン、API キー、パスワード)には ephemeral = true を使用し、状態ファイルに永続化されないようにしてください。実行間で保持する必要があるライセンスキーなどの長期間有効な値には、stable を使用してください。

Required Providers ブロック
required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 6.0"
  }
  random = {
    source  = "hashicorp/random"
    version = "~> 3.5.0"
  }
}
Provider ブロック

Provider ブロックは、従来の Terraform とは異なります。

  1. for_each メタ引数をサポートします
  2. エイリアスは引数ではなく、ブロックヘッダーで定義します
  3. config ブロックを使用して構成を受け取ります

単一プロバイダーの構成:

provider "aws" "this" {
  config {
    region = var.aws_region
    assume_role_with_web_identity {
      role_arn           = var.role_arn
      web_identity_token = var.identity_token
    }
  }
}

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
    }
  }
}

認証のベストプラクティス:Stacks では、推奨される認証方法としてワークロードアイデンティティ(OIDC)を使用してください。この方法には、次の利点があります。

  • 長期間有効な静的認証情報を回避できます
  • デプロイメントの実行ごとに、一時的でスコープが限定された認証情報を提供します
  • クラウドプロバイダーの IAM(AWS IAM ロール、Azure マネージド ID、GCP サービスアカウント)と連携します
  • プラットフォーム管理の環境変数が不要になります

プロバイダー構成で identity_token ブロックと assume_role_with_web_identity を使用して、ワークロードアイデンティティを設定します。AWS、Azure、GCP の詳しい設定手順については、次を参照してください:https://developer.hashicorp.com/terraform/cloud-docs/dynamic-provider-credentials

コンポーネントブロック

各 Stack には、少なくとも 1 つのコンポーネントブロックが必要です。Stack に含めるモジュールごとにコンポーネントを追加してください。コンポーネントは、ローカルパス、レジストリ、または 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
  }
}

依存関係、for_each、公開レジストリのモジュール、Git ソースなどの例については、references/component-blocks.md を参照してください。

主なポイント:

  • 出力を参照する場合:component.<name>.<output> または for_each の場合は component.<name>[key].<output>
  • コンポーネントの参照から依存関係が自動的に推測されます
  • for 式で集約します:[for x in component.s3 : x.bucket_name]
  • for_each を使用するコンポーネントでは、特定のインスタンスを参照します:component.<name>[each.value].<output>
  • プロバイダーの参照は通常の値です:provider.<type>.<alias> または provider.<type>.<alias>[each.value]
出力ブロック

出力には type 引数が必要で、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
}
ローカルブロック

ローカルブロックは、.tfcomponent.hcl ファイルと .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}"
    }
  }
}
削除ブロック

Stack からコンポーネントを安全に削除するために使用します。HCP Terraform で削除するには、そのコンポーネントのプロバイダーが必要です。

removed {
  from   = component.old_component
  source = "./modules/old-module"

  providers = {
    aws = provider.aws.this
  }
}

デプロイ構成(.tfdeploy.hcl)

ID トークンブロック

クラウドプロバイダーとの OIDC 認証用に JWT トークンを生成します。

identity_token "aws" {
  audience = ["aws.workload.identity"]
}

identity_token "azure" {
  audience = ["api://AzureADTokenExchange"]
}

デプロイでは identity_token.<name>.jwt を使ってトークンを参照します。

ストアブロック

Stack のデプロイ内で HCP Terraform の変数セットにアクセスします。

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
  }
}

認証情報を一元管理し、Stack 間で変数を共有するために使用します。詳細については、references/deployment-blocks.md を参照してください。

デプロイブロック

デプロイインスタンスを定義します(Stack ごとに最小 1 個、最大 20 個)。

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
  }
}

デプロイを破棄するには:destroy = true を設定して構成をアップロードし、破棄の実行を承認してから、デプロイブロックを削除します。詳細については、references/deployment-blocks.md を参照してください。

デプロイグループブロック

共有設定のためにデプロイをグループ化します(HCP Terraform Premium ティアの機能)。Free/Standard ティアでは、{deployment-name}_default という名前のデフォルトグループが使用されます。

deployment_group "canary" {
  auto_approve_checks = [deployment_auto_approve.safe_changes]
}

deployment "dev" {
  inputs = { /* ... */ }
  deployment_group = deployment_group.canary
}

複数のデプロイで同じグループを参照できます。詳細については、references/deployment-blocks.md を参照してください。

デプロイ自動承認ブロック

デプロイ計画を自動承認するルールを定義します(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"
  }
}

使用可能なコンテキスト変数:context.plan.applyable、context.plan.changes.add/change/remove/total、context.success

注: orchestrate ブロックは非推奨です。代わりに deployment_group と deployment_auto_approve を使用してください。

すべてのコンテキスト変数とパターンについては、references/deployment-blocks.md を参照してください。

出力公開ブロックと上流入力ブロック

ある Stack の出力を公開し、別の Stack で利用することで、Stack 同士を連携させます。

# 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
  }
}

完全なドキュメントと例については、references/linked-stacks.md を参照してください。

Terraform Stacks CLI

注: Terraform CLI v1.13 以降では、Terraform Stacks は一般提供(GA)されています。HCP Terraform の課金では、Stacks も管理対象リソース(RUM)に含まれるようになりました。

初期化と検証
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
デプロイのワークフロー

重要: plan コマンドや apply コマンドはありません。構成をアップロードすると、デプロイの実行が自動的に開始されます。

# 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
構成管理
terraform stacks configuration list                    # List configuration versions
terraform stacks configuration fetch -configuration-id=...  # Download configuration
terraform stacks configuration watch                   # Monitor upload status
その他のコマンド
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

HCP Terraform API を使用したデプロイの監視

自動化、CI/CD、または非対話型環境(AI エージェントなど)でプログラムから監視する場合は、CLI の監視コマンドではなく HCP Terraform API を使用してください。API には、次のエンドポイントが用意されています。

  • 設定のステータスと検証
  • デプロイグループの概要
  • デプロイ実行のステータス
  • デプロイ手順の詳細(プラン/適用)
  • ファイルの場所とコードスニペットを含むエラー診断
  • アーティファクトエンドポイント経由のスタック出力

重要なポイント:

  • CLI の監視コマンドは無期限にストリームを出力するため、自動化では機能しません
  • スタック出力を取得するには、アーティファクトエンドポイントを使用します:GET /api/v2/stack-deployment-steps/{step-id}/artifacts?name=apply-description
  • 診断エンドポイントには、stack_deployment_step_id クエリパラメーターが必要です
  • アーティファクトエンドポイントは HTTP 307 リダイレクトを返します(curl -L を使用してください)

API ワークフロー全体、認証、ポーリングのベストプラクティス、スクリプトの例については、references/api-monitoring.md を参照してください。

一般的なパターン

コンポーネントの依存関係:あるコンポーネントが別のコンポーネントの出力を参照すると、依存関係が自動的に推定されます(例:subnet_ids = component.vpc.private_subnet_ids)。

マルチリージョンデプロイ:プロバイダーとコンポーネントに for_each を使用すると、複数のリージョンにデプロイできます。各リージョンには、独自のプロバイダー設定とコンポーネントインスタンスが割り当てられます。

遅延変更:Stacks は、値が適用後にのみ判明する依存関係に対応するため、遅延変更をサポートしています。これにより、一部のリソースが他のコンポーネントの実行時の値(クラスターエンドポイント、生成されたパスワードなど)に依存する、複雑なマルチコンポーネントデプロイが可能になります。

マルチリージョンデプロイ、コンポーネントの依存関係、遅延変更のパターン、リンクされた Stacks を含む完全な例については、references/examples.md を参照してください。

ベストプラクティス

  1. コンポーネントの粒度:ライフサイクルを共有する論理的なインフラストラクチャ単位ごとにコンポーネントを作成します
  2. モジュールの互換性:
    • Stacks で使用するモジュールにはプロバイダーブロックを含められません(プロバイダーは Stack の設定で構成します)
    • 本番環境の Stacks で使用する前に、パブリックレジストリのモジュールをテストしてください。一部のモジュールには互換性の問題がある場合があります
    • モジュールの互換性が不明な場合は、重要なインフラストラクチャに未加工のリソースを使用することを検討してください
    • 例:terraform-aws-modules の一部のバージョンには、Stacks との互換性の問題があることが確認されています(例:ALB および ECS モジュール)
  3. 状態の分離:各デプロイには、独立した状態が割り当てられます
  4. 入力変数:デプロイごとに異なる値には変数を、共通の値にはローカル値を使用します
  5. プロバイダーのロックファイル:.terraform.lock.hcl を必ず生成し、バージョン管理にコミットします
  6. 命名規則:コンポーネントとデプロイには、内容が分かる名前を付けます
  7. デプロイグループ:デプロイをデプロイグループに整理できます。デプロイグループを使用すると、自動承認ルールや論理的な整理が可能になり、スケーリングの基盤にもなります。デプロイグループは、HCP Terraform の Premium ティアの機能です
  8. テスト:本番環境の前に、開発/ステージングのデプロイで Stack の設定をテストします

トラブルシューティング

循環依存:循環参照が解消されるようリファクタリングするか、中間コンポーネントを使用してください。

デプロイの破棄:UI からは破棄できません。デプロイブロックで destroy = true を設定して設定をアップロードすると、HCP Terraform が破棄実行を作成します。

診断が空の場合:診断 API リクエストに必須の stack_deployment_step_id クエリパラメーターを追加してください。

モジュールの互換性:本番環境で使用する前に、パブリックレジストリのモジュールをテストしてください。一部のモジュールには、Stacks との互換性の問題がある場合があります。

参考資料

詳細なドキュメントについては、以下を参照してください。

  • references/component-blocks.md - すべての引数と構文を含む、コンポーネントブロックの完全なリファレンス
  • references/deployment-blocks.md - すべての設定オプションを含む、デプロイブロックの完全なリファレンス
  • references/linked-stacks.md - スタックを相互にリンクするための、出力の公開と上流入力
  • references/examples.md - マルチリージョンとコンポーネント依存関係の完全な動作例
  • references/api-monitoring.md - プログラムによるモニタリングと自動化のための、API ワークフロー全体
  • references/troubleshooting.md - よくある問題と解決策を詳しく説明したトラブルシューティングガイド

コメント