はじめに
こんにちは。普段IaC (Infrastructure as Code) エンジニアをしている者です。
HCP Terraformを現場で利用していて知見がたまってきたので、記事としてまとめました。
全ての機能を網羅しているわけではありませんが、これからHCP Terraformを利用する方や、利用しているけどまだ設定していない機能がある方の参考になれば幸いです。
前提として、HCP Terraformが何かをなんとなく知っている方向けの記事になります。
この記事では以下の流れで説明します。
- 概要
- HCP Terraform の全体像
- Organization 設定
- Project 設定
- Workspace 設定
概要
HCP Terraform は Organization → Project → Workspace という3階層の管理構造を持っています。
- Organization:HCP Terraform の最上位の管理単位。チームや共通設定(Variable Sets、Policy Sets)を管理します
- Project:関連する Workspace をグループ化する単位。システムや担当チームごとに作成します
- Workspace:Terraform の State を管理する最小単位。環境(prod、stg)やコンポーネントごとに作成します
設定は Organization → Project → Workspace の順に進めると効率よく構成できます。
1. HCP Terraform の全体像
まずは、HCP Terraform を中心とした IaC 運用の全体像を説明します。
1.1. アーキテクチャ概要
以下の図は、HCP Terraform を中心とした各コンポーネント間の関係性を示しています。
1.2. ワークフロー詳細
HCP Terraform を用いた開発からデプロイ、監視までの一連のフローを説明します。
ここではVCS連携+Tag-based Triggersを前提としたフローを紹介(それぞれ設定として後述)します。
1.2.1. 日常的な開発フロー
-
コード編集:開発者がローカル環境でブランチを切り Terraform コードを編集します
-
コミット・プッシュ:変更を GitHub リポジトリにプッシュします
-
Pull Request 作成:Pull Request を作成すると、HCP Terraform が自動的に Speculative Plan を実行します
-
レビューとマージ:レビュー承認後、main ブランチへマージします
1.2.2. デプロイフロー
-
タグ作成:デプロイ準備が整ったら、main ブランチに Git タグを作成します
-
Run トリガー:タグがプッシュされると、HCP Terraform Workspace で Run が自動的にトリガーされます
-
Plan 実行:HCP Terraform が Plan を実行し、変更内容を表示します
-
Apply 実行:承認者が Plan の内容を確認し、Apply を実行してクラウドリソースをデプロイします
1.2.3. 継続的な監視
-
Drift Detection:定期的に実際のクラウド環境と Terraform State を比較し、差分を検出します
-
通知:Run の状態変化や Drift 検出時に、Slack や Email で通知を受け取ります
1.3. セキュリティとガバナンス
1.3.1. OIDC 認証
HCP Terraform とクラウドプロバイダー間の認証には OIDC を使用できます。
OIDCにより、長期的な認証情報(Client Secret など)を HCP Terraform に保存する必要がなくなり、セキュリティが向上します。
1.3.2. Policy Sets によるガバナンス
Policy Sets を利用することで、以下のガバナンスを実現します。
- 必須タグの検証
- 命名規則の検証
- コスト制限
- セキュリティ設定の検証
Policy Sets は Plan 実行時に自動的にチェックされ、ポリシー違反がある場合は警告または実行中断されます。
1.3.3. アクセス制御
Teams 機能により、Organization、Project、Workspace の各レベルできめ細かなアクセス制御を実現します。
Team ごとに必要最小限の権限のみを付与することで、不要なアクセスや誤操作による影響を最小化できます。
2. Organization 設定
Organization は HCP Terraform における最上位の管理単位です。
組織全体で共通利用する設定を行うことで、Project や Workspace の作成時に効率的な設定が可能となります。
2.1. Tags の作成
HCP Terraform の Tag 機能を利用することで、Project や Workspace を分類・管理できます。
コスト管理や各Workspaceの管理のために利用できます。
Tag を事前に登録しておくことで、Project 作成時に一貫性のあるタグ付けが可能となります。
2.1.1. Tag の命名例
例えば以下のようにTagを付与することで、後のコスト分析をしやすくしました。(現状、別途コストを集計する仕組みを実装する必要あり)
EnvironmentDepartmentSystem
2.2. Teams の設定
Teams 機能を利用することで、Organization 内でのアクセス制御を実現できます。
基本的に以下のようにTeamを管理すると管理しやすいです。
- 基本的にTeam に対して権限を付与し、メンバーを追加 (メンバ直接は付与しない)
- Teamは後述するProjectレベルで管理
2.3. Variable Sets(Organization レベル)の作成
Variable Sets を利用することで、複数の Project で共通利用する変数をまとめて管理できます。
Variable setsはProject レベルでも作成できるため、全体で共通利用する変数とProject レベル変数を分けてあげるとよいです。
2.3.1. Variable Set の適用範囲
Variable Set の作成時には、以下の適用範囲を選択できます。
- Apply to all projects and workspaces:Organization 内の全体に適用
- Apply to specific projects and workspaces:特定の Project または Workspace にのみ適用
2.3.2. 変数の種類
Variable Set には以下の2種類の変数を追加できます。
- Terraform variable:Terraform コード内で参照する変数
- Environment variable:実行環境で参照する環境変数
Terraformの機能を使いやすいため、基本的にTerraform variableでの定義がよいです。
Secret 情報を扱う場合は、変数に「Sensitive」フラグを設定することで、値がマスクされます。
2.3.3. Organization レベルで設定する変数の例
Organization 全体で共通利用する変数の例を以下に示します。
| Key | Value 例 | Type | 説明 |
|---|---|---|---|
region |
japaneast |
Terraform | 東日本リージョンのみを使う場合 |
default_tags |
HCL 形式 | Terraform | 全リソースに適用する共通タグ |
注意: プロジェクトごとに異なる値(認証情報、プロジェクト固有の識別子など)は Organization レベルでは設定せず、Project レベルまたは Workspace レベルで設定してください。
2.4. Policy Sets の設定
Policy Sets を利用することで、Terraform コードに対するガバナンスルールを適用できます。
Sentinel または OPA(Open Policy Agent)形式でポリシーを記述し、Plan 実行時にポリシーチェックを行います。
Policyでも同じことができますが、Policy setsはGitHub repository等で管理できるため、コードレビューやバージョン管理がしやすいです。
※Projectの途中でTerraformを導入した場合は、手動での管理とTerraformでの管理が混在していることが多いです。その場合、Terraformで管理しているリソースのみを対象にできます。Policy setsでガバナンスを管理する場合は、すべての手動管理リソースをTerraform管理に切り替えることを推奨します。
2.4.1. Policy Set の接続方法
Policy Set はいくつかの方法で管理できますが、規模が大きくなることを考えるとVCS (Version Control System) 連携が推奨です。
- VCS 連携:GitHub などの VCS リポジトリと連携してポリシーを管理
2.4.2. Policy の適用範囲と強制レベル
適用範囲:
- Policies enforced globally:全 Workspace に適用
- Policies enforced on selected projects and workspaces:特定の Project または Workspace にのみ適用
全体とProjectごとに適用するポリシーを分けることができます。
Enforcement mode(強制レベル):
- Advisory:警告のみで実行は継続可能
- Soft mandatory:ポリシー違反時に警告を表示するが、権限があれば上書き可能
- Hard mandatory:ポリシー違反時は実行を中断(上書き不可)
SoftとHardの違いは分かりづらいですが、Softの場合は上書き権限を持っていればポリシー違反を無視できます。Hardの場合はポリシー違反を無視できません。
2.4.3. Policy Sets の活用例
組織で一般的に適用されるポリシーの例を以下に示します。
- 必須タグの検証:すべてのリソースに必須タグが付与されているかを確認
- 命名規則の検証:リソース名が組織の命名規則に準拠しているかを確認
- コスト制限:高額なリソースタイプの利用を制限
- セキュリティ設定の検証:Public Access や暗号化設定が適切に構成されているかを確認
2.5. VCS Connections の設定
HCP Terraform から GitHub などの VCS プロバイダーに接続するための設定を行います。
VCS 接続を事前に設定しておくことで、Workspace 作成時にスムーズに VCS 連携を構成できます。
2.5.1. 対応する VCS プロバイダー
HCP Terraform は以下の VCS プロバイダーに対応しています。
- GitHub.com
- GitHub Enterprise Server
-
GitLab
等
一覧:https://developer.hashicorp.com/terraform/cloud-docs/vcs
VCS 接続には OAuth Application の登録が必要です。OAuth Applicationの権限範囲に注意
2.6. Private Registry の活用
HCP Terraform の Private Registry を利用することで、組織内で共有するモジュールを一元管理できます。
ローカルモジュールを Private Registry に移行することで、バージョン管理やモジュールの再利用性が向上します。
2.6.1. Private Module の移行(ローカルで管理しているモジュールがある場合)
ローカルで管理していたモジュールを HCP Terraform Private Registry に移行することで、バージョン管理やモジュールの再利用性が向上します。
ただし、ある程度汎用化が必要になるためモジュール化には時間がかかります。スコープを絞って段階的に移行するとよいです。
モジュールリポジトリの例
-
リポジトリ名が
terraform_<モジュール名>とする
例:terraform_aws_security_group -
リポジトリに以下ファイルを配置
-
main.tf:モジュールのメインロジック -
variables.tf:入力変数の定義 -
outputs.tf:出力値の定義 -
README.md:モジュールの使用方法を説明するドキュメント
-
-
モジュールのバージョンを示す Git タグが付与されていること
例:v1.0.0,v1.1.0
モジュールを VCS リポジトリと連携して公開することで、タグの作成時に自動的に Private Registry にバージョンが追加されます。
git tag v1.0.0
git push origin v1.0.0 # <- これで HCP Terraform Private Registry に v1.0.0 が公開される
Private Module の参照方法
Private Registry に公開したモジュールは、以下の形式で参照できます。
module "example" {
source = "app.terraform.io/<organization名>/<module_name>/<provider>"
version = "1.0.0"
# モジュールへの入力変数
}
2.6.2. Module Test の作成
Private Module の品質を保つため、モジュールに対するテストを作成することを推奨します。
テストファイルの配置
モジュールリポジトリ内に tests/ ディレクトリを作成し、その中に .tftest.hcl 拡張子のテストファイルを配置します。
terraform-provider-module/
├── main.tf
├── variables.tf
├── outputs.tf
├── README.md
└── tests/
└── *.tftest.hcl
テストがなくてもモジュールを利用できますが、テストがない場合、一度モジュールを公開してから各 Workspace で動作確認する必要があるため、動作の担保が難しくなります。実質必須です。
3. Project 設定
Project は、関連する Workspace をグループ化するための単位です。
同一のシステムや環境に属する Workspace をまとめて管理することを推奨します。
3.1. Project の作成
Project 作成時には、以下の情報を設定します。
-
Project 名:例:
systemA - Description:Project の用途(任意)
- Tags:Organization レベルで作成した Tag を選択
複数のWorkspace(後述)をまとめる単位です。例えば各Workspaceにinfra, app, database等を作成し、それらをsystemAというProjectにまとめるイメージです。
3.1.1. Project への Team 権限の設定
Project に対して Team ごとのアクセス権限を設定します。
- Admin:Project の設定変更と Workspace の管理が可能
- Write:Workspace の作成と Run の実行が可能
- Read:Workspace の閲覧のみ可能
原則は最小権限です。プロジェクトの要件に応じた設計が必要になります。
3.2. Variable Set(Project レベル)の作成
Project 配下の複数 Workspace で共通利用する変数を Variable Set として定義します。
Variable Set の適用範囲は以下を選択できます。
- Apply to the entire project (基本的にこちらを利用):Project 内の全 Workspace に適用
- Apply to specific workspaces in the project (必要に応じて):特定の Workspace にのみ適用
Apply to the entire projectで管理することで、同一Project内のWorkspaceで共通の変数を効率的に管理できます。
3.2.1. Project レベルで設定する変数の例
Project レベルでは、主に認証に必要な環境変数を設定します。
Terraform variables:
| Key | 説明 |
|---|---|
account_id/subscription_id等 |
リソースのデプロイ先リージョン |
4. Workspace 設定
Workspace は、Terraform の State を管理する単位です。
環境(production, staging など)やモジュールごとに Workspace を作成することを推奨します。
4.1. Workspace の作成と VCS 連携
4.1.1. ワークフロー方式の選択
HCP Terraform には複数の実行方式が存在します。
- VCS Driven Workflow:GitHub などの VCS と連携し、コードのプッシュやタグ作成を契機に自動的に Run を実行
-
CLI Driven Workflow:ローカル環境から
terraform plan/terraform applyコマンドを実行 - API Driven Workflow:API 経由で Run を作成・実行
VCS Driven Workflow の採用を推奨します。
VCS と連携することで、コードレビューのプロセスを経た変更のみをデプロイすることが可能となり、変更履歴の追跡も容易になります。
4.1.2. Workspace の基本設定
Workspace 作成時には、例えば以下のような項目を設定できます。いろいろ設定があるため、細かくは割愛します。
- VCS provider:事前に設定した VCS Connection を選択
-
Workspace 名:例:
infrastructure-production - Terraform Working Directory:Terraform コードが格納されているディレクトリパス。リポジトリ内にdev/stg/prod等のディレクトリがある場合は、ここで指定する。
- Auto-apply:手動承認をする場合、チェックを入れない
特に Terraform Working Directory の設定は、モノレポ構成(1つのリポジトリに複数の Workspace を持つ構成)の場合に重要です。
4.1.3. Run トリガー方式の選択
-
Branch-based:特定のブランチ(例:
main)への変更を契機に Run を実行 - Tag-based:特定のパターンに合致するタグの作成を契機に Run を実行
Tag-based Triggers の採用を推奨します。
タグベースのトリガーを利用することで、デプロイのタイミングを明示的に制御でき、意図しない変更の自動適用を防ぐことができます。
また、タグにバージョン情報やリリース日時を含めることで、デプロイ履歴の管理が容易になります。
ただし、デプロイ時にタグ指定で前のバージョンに戻ることはできないため、一度Repositoryをrevertしてからタグを作成する等の運用が必要になります。適用対象のバージョンを指定できるようにアップデートを期待してます。
Pull Request との連携:
「Automatic speculative plans」を有効にすることで、Pull Request 作成時に自動的に Speculative Plan が実行され、変更内容を事前に確認できます。
4.1.4. Workspaceの分割
terraform単体で運用しているときと同様に、適切な粒度でstatefileを分割します。statefileの単位がWorkspaceになります。プロジェクトの規模によりますが、例えば以下のように分割します。
- SystemA-infra
- SystemA-data
- SystemA-app
4.2. Terraform コードの設定
HCP Terraform とクラウドプロバイダーを連携させるために必要な Terraform コードの設定方法を説明します。
4.2.1. versions.tf の設定
HCP Terraform と連携するには、terraform.cloud ブロックで Organization 名と Workspace 名を指定します。
terraform {
cloud {
organization = "my-organization"
workspaces {
name = "my-workspace"
}
}
}
設定項目の説明:
-
organization:HCP Terraform の Organization 名を指定します -
workspaces.name:連携する Workspace 名を指定します
4.2.2. providers.tf の設定
providers.tf には、プロバイダーの認証設定を記述します。
OIDC 認証を採用している場合、use_oidc = true を指定します。
基本的な Provider 設定
provider "azurerm" {
use_oidc = true
features {}
}
動的認証情報の利用
HCP Terraform が提供する動的認証情報を利用する場合の設定例です。
variable "tfc_cloud_dynamic_credentials" {
description = "Dynamic credentials provided by HCP Terraform"
type = object({
default = object({
client_id_file_path = string
oidc_token_file_path = string
})
})
}
provider "azurerm" {
use_oidc = true
client_id_file_path = var.tfc_cloud_dynamic_credentials.default.client_id_file_path
oidc_token_file_path = var.tfc_cloud_dynamic_credentials.default.oidc_token_file_path
features {}
}
上記の設定は、1Workspace内で1つのOIDC認証情報を利用する場合は必須ではないですが、
複数のOIDC認証情報を利用する場合は必須になります。
詳細はこの記事を参照してください。https://qiita.com/hsmto25519/items/4504b1da40a6b9af5f91
4.3. クラウドプロバイダー側の設定(OIDC 認証)
HCP Terraform からクラウドリソースにアクセスするため、クラウドプロバイダー側に OIDC 認証の設定を行います。
この設定により、Secret 情報を HCP Terraform に保存することなく、安全に認証できます。
Azureを例に説明します。他のクラウドプロバイダを利用する場合は各ドキュメントを参照してください。
4.3.1. 認証アプリケーションの登録
クラウドプロバイダーのコンソールでアプリケーションを登録し、Service Principal を作成します。
Azure の場合の例:
- ID 管理サービス(Microsoft Entra ID)でアプリケーションを登録
- アプリケーション名を設定(例:
hcp-terraform-oidc) - 発行されるクライアント ID と テナント ID を控える
4.3.2. アクセス権限の付与
Service Principal に対して、必要なリソースへのアクセス権限を付与します。
対象のスコープ(サブスクリプション、プロジェクトなど)で適切なロールを割り当てます。
- リソースの作成・変更・削除が必要な場合:共同作成者または編集者ロール
- 読み取り専用の場合:閲覧者またはリーダーロール
4.3.3. フェデレーション資格情報の追加
HCP Terraform の Run(Plan / Apply)ごとに OIDC トークンを発行し、クラウドプロバイダーに認証できるようにします。
フェデレーション資格情報の設定項目:
-
発行者(Issuer):
https://app.terraform.io -
サブジェクト(Subject):
organization:<organization名>:project:<プロジェクト名>:workspace:<ワークスペース名>:run_phase:* -
Audience:
api://AzureADTokenExchange(Azure の場合)
注意: サブジェクトの run_phase には wildcard (*) を使用することで、Plan と Apply の両方で同じ資格情報を利用できます。
4.4. Health と Notification の設定
Workspace の Health チェックと通知設定を行うことで、Drift の検出や Run の状態変化を監視できます。
4.4.1. Drift Detection の有効化
Drift Detection を有効にすることで、実際のクラウド環境と Terraform State を定期的に比較し、差分を検出できます。
検出の実行間隔は Daily、Weekly、Custom から選択可能です。
Drift DetectionはOrganizationレベルで全Workspaceに適用も可能です。
4.4.2. Notification の設定
Notification を設定することで、Run の状態変化をリアルタイムに把握できます。
通知先の種類:
- Slack
- Microsoft Teams
- その他
詳細はこちら:https://developer.hashicorp.com/terraform/cloud-docs/workspaces/settings/notifications
最後に
主にHCP Terraform を活用するための最低限の設定について説明しました。
冒頭に記載しましたが、すべての機能を網羅しているわけではないので、HCP Terraform のドキュメントを参照しながら、必要に応じて追加の機能も検討してみてください。
一から設定するのは大変ですが、最初にしっかりと構成を考えて設定しておくことで、運用が格段に楽になります。
ぜひこれをベースにして、組織やプロジェクトの要件に合わせた最適な構成を検討してみてください。
内容には気をつけておりますが、万が一誤字や間違いなどあれば、教えていただけますと幸いです。
以上です、最後まで読んでいただきありがとうございました!
