APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Terraform Stacks の機能と使い方を紹介

先日の HashiConf 2024 にて、HCP Terraform の新機能「Terraform Stacks」が公開されました!

Terraform Stacks とは

Terraform Stacks は単一の Terraform 構成で複数のインフラ環境を管理して、複雑化したインフラ環境の管理を簡素化・効率化できる機能です。 既存のルートモジュールを置き換え、子モジュールの上に新しいレイヤーを追加することによって、Terraform Stacks は IaC の概念を拡張しています。

従来の HCP Terraform では1ワークスペースで1環境の管理しかできませんでした。 例えば、1つのリポジトリに Terraform 構成を格納して、そのリポジトリを使って本番/ステージング/開発環境を構築する場合、各環境に応じたワークスペースを作って管理が必要でした。

Terraform Stacks を使うことで複数環境の構成を管理する場所を1つに集約できます。 厳密には Terraform Stacks はワークスペースを使わず、上位概念のプロジェクトの中で管理されます。

HashiCorp の公式ブログにも Terraform Stacks 紹介記事がありますので、ぜひ確認してみてください。

www.hashicorp.com

試してみる

それでは、Terraform Stacks の構造的な理解を深めるために hashicorp-guides/pet-nulls-stack というサンプルリポジトリを使って実際に Terraform Stacks を動かしてみましょう。

引用元: https://github.com/hashicorp-guides/pet-nulls-stack

Terraform Stacks の構成要素

まずはリポジトリに用意されたコードを見ながら Terraform Stacks の構成要素を見ていきます。

このサンプルリポジトリで「Pet」と「Nulls」という2つのコンポーネントと「Simple」と「Complex」というの2つデプロイメントが用意されています。

コンポーネント

最初にコンポーネントです。 コンポーネントでは Terraform Stacks でデプロイする Terraform モジュールを指定します。 新しく追加された .tfstack.hcl という拡張子のファイルに記述したモジュールは Terraform Stacks により同じライフサイクルで作成、管理されます。

以下は hashicorp-guides/pet-nulls-stackcomponents.tfstack.hcl の抜粋です。

component "pet" {
  source = "./pet"

  inputs = {
    prefix = var.prefix
  }

  providers = {
    random = provider.random.this
  }
}

component "nulls" {
  source = "./nulls"

  inputs = {
    pet       = component.pet.name
    instances = var.instances
  }

  providers = {
    null = provider.null.this
  }
}

ここでは新しく追加された component ブロックで次の3つの要素を定義します。

  • 呼び出すモジュールのパス
  • モジュール呼び出し時の入力値
  • モジュール呼び出し時に利用するプロバイダー

また、各 component ブロックで呼び出されたモジュールの output は他のブロック(component や provider)でも利用できます。 これにより各コンポーネント間の依存関係が生まれて Terraform Stacks でデプロイするときの順番などが決まります。

Terraform モジュールでも同じことできるのでは?という気もしましたが、おそらく component ブロックの依存関係は Terraform Stacks が持っている「Deferred Changes」という機能を実現するためにも使われていると想像します。

デプロイメント

次にデプロイメントです。 コンポーネントと同じく新しく追加された .tfdeploy.hcl という拡張子のファイルに Terraform Stacks で構築する環境を定義します。

以下は hashicorp-guides/pet-nulls-stackdeployments.tfstack.hcl の抜粋です。

deployment "simple" {
  inputs = {
    prefix           = "simple"
    instances        = 1
  }
}

deployment "complex" {
  inputs = {
    prefix           = "complex"
    instances        = 3
  }
}

これまた新規の deployment ブロックで環境毎の入力値を設定します。 このサンプルリポジトリでは simple デプロイメントと complex デプロイメントという2つの環境を構築するように定義しており、それぞれ prefix と instances の変数を変えることで環境によるインフラ構成の違いを表しています。

pet モジュール / nulls モジュール

コンポーネントから参照されているモジュールを見ていきます。

pet モジュールは入力値 prefix に3単語のランダム文字列を付与して name として出力するモジュールです。

# pet/main.tf

terraform {
  required_providers {
    random = {
      source = "hashicorp/random"
      version = "3.3.2"
    }
  }
}

variable "prefix" {
  type = string
}

resource "random_pet" "this" {
  prefix = var.prefix
  length = 3
}

output "name" {
  value = random_pet.this.id
}

nulls モジュールは入力値 pet をトリガーとする null_resource を入力値 instances の数だけ作成して ids として出力するモジュールです。

# nulls/main.tf

terraform {
  required_providers {
    null = {
      source = "hashicorp/null"
      version = "3.1.1"
    }
  }
}

variable "pet" {
  type = string
}

variable "instances" {
  type = number
}

resource "null_resource" "this" {
  count = var.instances

  triggers = {
    pet = var.pet
  }
}

output "ids" {
  value = [for n in null_resource.this: n.id]
}

これらの2つのモジュールは独立しています。 既存のモジュールをそのまま使えるように Terraform Stacks は構成されています。

一方、上位の components.tfstack.hcl にて「 pet モジュールの出力結果を nulls モジュールの入力とする」ように定義されています。 そのため、nulls モジュールを実行するには pet モジュールが実行されていることが条件の依存関係が生まれています。


Terraform Stacks を使うために最低限必要な Terraform 構成は以上です。

主に新たに追加された .tfstack.hcl. tfdeploy.hcl のファイルが必要になります。 コンポーネントとして参照するモジュールは HCP Terraform 上の Private registry も参照できるようです。

HCP Terraform の操作

それでは HCP Terraform を操作して先程のサンプルリポジトリを元に Terraform Stacks を作ってみましょう。

前提条件として、サンプルリポジトリを HCP Terraform から参照できるアカウントにフォークしておいてください。 また、Terraform Stacks という機能で HCP Terraform 上に作成するものを「Stack」と記載しています。

Terraform Stacks 設定

HCP Terraform のプロジェクトを選択するとワークスペース一覧の他に「Stacks (Beta)」という項目が追加されています。

Stack を新規追加してみます。

ワークスペースの作成時と同じように、HCP Terraform と連携させた GitHub などの VCS のリポジトリを選択する画面が出てきます。 ここでサンプルリポジトリ(をフォークしたリポジトリ)を選択します。

Stack 個別の設定もできますが、今回はデフォルトのままにしました。

ちなみに Advanced Options では連携するリポジトリのブランチやタグを指定できます。

Stack の作成が完了すると HCP Terraform 上に概要ページが表示されました。

ページ下部の「Deployment rollout」を見ると、デプロイメント complex と simple が表示されており、それぞれ「1 plan waiting for approval」となっています。

リソース作成

simple デプロイメントを選択してみると、通常のワークスペースのように Plan が承認待ちの状態で止まっていました。 当然このタイミングでは random_pet で作られるランダム文字列は判明していないため「Known after apply」と表示されています。

この Plan を承認するとコンポーネントで定義されたモジュールが実行されて各リソースが作られました。

またちょっとした違いですが、従来のワークスペースでは Plan と Apply の結果が上下に分かれて表示されていましたが、Terraform Stacks では Plan で表示されていた箇所に Apply 結果も表示される、つまり内容が更新される UI となっていました。

そして「Replan triggered」と表示されているように、Apply 後に再度 Plan が実行されていました。

「View replan」から再実行された Plan 結果を見ることができます。 簡単なリソースを一度 Apply を実行した直後なので差分もありません。

これは従来のワークスペースでの「Plan & Apply」とは異なる挙動です。

ここまでで Terraform Stacks を使って1つの環境(simple デプロイメント)にリソースを作成できました。 他の環境(complex デプロイメント)も同じように Plan 後の承認待ちとなっているため、承認することで simple デプロイメントと同じモジュールが実行されます。 モジュールの作り方にも依りますが、Terraform Stacks で作るリソースはデプロイメントの入力値を変えることで環境毎に変えられます。

今回は各環境で承認作業が必要でしたが、Terraform Stacks は Orchestration rules という機能を使うことで条件に合致した Plan を HCP Terraform が承認して自動的に Apply を実行できます。 Orchestration rules の使い方は別記事にて紹介します。

Terraform Stacks の削除

Terraform Stacks における削除対象は3つあります。

  1. Stack のデプロイメント毎に作ったリソース
  2. Stack のデプロイメント設定
  3. Stack

基本的には「リソース→デプロイメント→Terraform Stacks」の準備で削除していくことになります。

リソース

Terraform Stacks で作成したリソースを削除する場合、デプロイメントの「Destruction and deletion」から Destroy plan を作成します。

しばらくすると対象のデプロイメントで管理されているリソースを削除する Plan が実行されて承認待ちの状態となっています。 この Destroy plan を承認することで Terraform Stacks で作ったリソースが削除されます。

デプロイメント

デプロイメントはリソースが存在する間は削除できません。 リソースがない状態だと「Delete deployment xxxx from xxx」というボタンが表示されます。

Stack

Stack の「Destruction and Deletion」からはリソースの削除はできず、Stack のみ削除されることになるので注意が必要です。

まとめ

今回 Terraform Stacks を実際に操作して理解したことをまとめてみます。

  • Terraform Stacks は複数環境をまとめて作成、管理できる
  • Terraform Stacks は HCP Terraform のワークスペースではなくプロジェクトで操作・管理する
  • 既存の Terraformモジュールは変更せずに Terraform Stacks で利用できる

Terraform Stacks には今回紹介した基本的な機能の他に「Deferred changes」と「Orchestration rules」と呼ばれる機能があります。 こちらは別記事にて紹介したいと思います。

Terraform Stacks を使うことで、複雑になってきた複数インフラ環境の管理が楽になるかもしれません。 まだパブリックベータ版が公開されたばかりですが、今後の動きにも注目したい機能の一つですね!