Terraform CloudでWorking Directoryを設定したVCS Triggerとapplyをやってみた

Terraform CloudでWorking Directoryを設定したVCS Triggerとapplyをやってみた

Terraform Cloud/EnterpriseでのWorking Directoryを使用したVCS Triggerで柔軟にリソース管理をしましょう
2025.09.04

はじめに

こんにちは、データ事業本部の渡部です。
今回はTerraform Cloudを使って、Working Directory(作業ディレクトリ)のブランチ更新をトリガーにしたapplyをやってみます。

今回の検証のきっかけとしては、最近になってWorkspaceの運用を見直すこととなり、Workspaceごとにapplyするリソースを選択したり、変数をTerraform CloudのVariablesではなくtfvarsファイルでWorkspaceごとに定義をしたくなったことにあります。
これまでTerraformプロジェクトのルートディレクトリのmainブランチのマージをトリガーにTerraformを動かしていましたが、それだと上記の要求を満たせません。
どうしようかとTerraform Cloudを眺めていたらVersion Controlで、Terraform Working DirectoryAutomatic Run triggeringを見つけました。

これはイケそうと思い、早速触ってみる次第です。

やってみる

Terraformの設定ファイルの作成

Terraformは以下の構成です。GitHubで管理します。

.
├── modules
│   ├── s3
│   │   ├── main.tf
│   │   └── variables.tf
│   └── sns
│       ├── main.tf
│       └── variables.tf
└── workspace
    ├── test-a
    │   ├── README.md
    │   ├── main.tf
    │   ├── terraform.auto.tfvars
    │   └── variables.tf
    └── test-b
        ├── README.md
        ├── main.tf
        ├── terraform.auto.tfvars
        └── variables.tf

test-a配下はmodules/s3を呼びバケットを作成、test-b配下はmodules/snsを呼びSNSトピックを作成するようにしています。
以下はS3を作成する資材の3ファイル分の抜粋です。SNSも同じようにworkspace側で変数を定義して、modulesに渡しています。

./modules/s3/main.tf
resource "aws_s3_bucket" "this" {
  bucket = var.bucket_name

  tags = {
    Name = var.bucket_name
  }
}
./workspace/test-a/main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

module "s3_bucket" {
  source = "../../modules/s3"

  bucket_name = var.bucket_name
}
./workspace/test-a/terraform.auto.tfvars
bucket_name = "test-a-cm-watanabe"

Terraform Cloudの設定

Terraform Cloudには2つのWorkspaceを用意しました。

Pasted image 20250903220328

GitHubとの連携は以下を参考に設定します。

https://dev.classmethod.jp/articles/tfe-provider-hcp-terraform-github/

さて今回の肝である設定ですが、Terraform Working Directoryに設定したい作業ディレクトリを設定します。
ここで設定したディレクトリの設定ファイルをもとにTerraformがinitしたりplanしたりapplyすることになります。
今回はワークスペース単位で作業ディレクトリを用意しているので、それぞれのワークスペースで作業ディレクトリを設定します。

Pasted image 20250903222416

続いてAutomatic Run triggeringの設定では、Only trigger runs when files in specified paths changeを選択します。
ここではVCSとして設定したリポジトリのどこのディクトリが変更あった際にTerraformをRunさせるかを設定します。
今回はWorking Directoryが変更時にRunさせたかったので、Prefixesを選択しました。自動的にWorking Directoryが表示されるので、そのままにします。

Pasted image 20250903222826

それぞれのWorkspaceのVariablesで、Terraform CloudからAWSのリソースを操作する際に必要な資格情報として、Environment Variableを設定します。

Pasted image 20250903223333

私の環境ではすでに準備していたのですが、OIDCでAWSと連携をさせておく必要があります。
詳しい手順は以下をご参考ください。

https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/aws-configuration

なおその他のVariablesはterraform.auto.tfvarsから値を渡すため、設定をしていません。

こちらでWorkspaceの設定は完了です。

実行

Terraformを動かすために、GitHubにREADME.mdをtest-aワークスペース作業ディレクトリ(./workspace/test-a)に対して配置しました。

Pasted image 20250903224840

planが動きました。

Pasted image 20250903224935

test-bのワークスペースの方はterraformが動いていません。作業ディレクトリの設定がしっかり反映されていますね。
Pasted image 20250903225145

test-bの作業ディレクトリ(./workspace/test-b)に対しても同じようにREADMEを配置しました。
Pasted image 20250903225408

test-bのワークスペースのTerraformが動きました。
Pasted image 20250903225509

どちらもapplyをして、試しにS3コンソールを確認すると、バケットが作成されてました。
Pasted image 20250903232332

さいごに

いかがでしたでしょうか。
Terraform Cloud/Enterpriseで作業ディレクトリを分けつつWorkspaceごとにモジュールを選択して管理するにはWorkingDirecoryをWorkspaceに設定するこの方法がよさそうです。

ちなみに私はこれまでTerraform OSSのWorkspaceと、Terraform Cloud/EnterpriseのWorkspaceを同じものと思っていましたが、異なるものと認識した方がいいなと思いました。
というのも前者はステート分割の単位ですが、後者はTerraform Cloud/Enterpriseでリソースを管理するには必要なもので環境を定義する単位です。変数や実行履歴・ポリシーや権限など、ステート分割の単位より広い意味を持っていると思いました。

OSSのWorkspaceは同じTerraformでステート分割をしてリソース管理ができることに秀でており、複数の環境を払い出す際もWorkspaceで払い出すことにより、プラグインを再利用することができるよねという理解です。
一方作業ディレクトリを用意した払い出しはプラグインの再利用はせずに、そのディレクトリごとにプラグインをインストールをすることになります。
そのためWorkspaceと作業ディレクトリは相入れない関係のように思っていました。
しかしTerraform Cloud/Enterpriseにおける作業ディレクトリはコードの場所を示すポインタの補完的役割を担っています。
これによって1リポジトリで複数のリソースを管理するモノレポ構成でも、Workspaceと作業ディレクトリで柔軟に管理可能となるわけです。

以上です。
どなたかのご参考になれば幸いです。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.