HCP Terraformは基本的にはUI操作により各種設定を行っていきますが、HCP Terraform自体をTerraformコードにより管理する方法もあります。本記事では、HCP TerraformをTerraformにより管理する方法を紹介します。
また、HCP Terraformを作成したTerraformのtfstateを保管する場所も重要です。AWS S3のようなクラウドストレージに保管してもいいですが、ここではHCP Terraformで自己管理させることにします。
なお、本記事はHCP Terraformについてある程度理解していることを前提としています。また、HCP TerraformとGitHubを連携させていることも前提としております。
概要
なぜTerraformでHCP Terraformを管理するのか
UIで設定できる項目でも、Terraform・Gitで管理すると以下の利点があります。
-
変更履歴がGitに残る
- いつ、誰が、何を、なぜ変更したかをコミット履歴で追跡できる
- UI上の変更では残しにくい「変更理由」もPR本文に記録できる
- 障害時に「どの設定変更が影響したか」を切り戻し含めて検証しやすい
-
PRレビューを通して設定変更できる
- 変更前に複数人で設定妥当性を確認でき、設定ミスの早期検知につながる
- 承認フローを標準化することで、権限の強い設定変更でも統制を効かせやすい
- 「UIで直接変更した人しか意図が分からない」状態を避けられる
-
環境(dev/stg/prd)間で同じルールを再利用できる
- モジュールや共通変数を使って、命名規則・実行モード・変数方針を横展開できる
- 環境ごとの差分は入力値に限定しやすく、設定ドリフトを抑えられる
- 新規環境追加時も既存コードを流用でき、立ち上げ時間を短縮できる
-
手作業の設定漏れを減らせる
- 変数、Variable set、Workspace設定をコード化することで作業手順の属人化を抑える
-
terraform planで意図しない差分を事前に確認できる - importを併用すれば既存UI資産も段階的にコード管理へ移行できる
特に、Workspace数やProject数が増えるほど、UI中心運用では差分管理と再現性の維持が難しくなります。
最初は「共通Variable setの管理」や「新規Workspace作成」など範囲を小さく始め、運用に合わせて管理対象を広げるのが現実的です。
使用するプロバイダー
HCP Terraform(Terraform Cloud)のリソースは、HashiCorp公式のhashicorp/tfeプロバイダーで管理します。
terraform {
required_version = ">= 1.8.5"
required_providers {
tfe = {
version = ">= 0.72"
source = "hashicorp/tfe"
}
}
}
provider "tfe" {}
ここの詳しい設定については、後述する"実装例"の章で解説します。
実装例
以下の例では以下のように作成していきます。
- 1~5章
- Organizaton、Project、WorkspaceをTerraformにより作成
- 6章
- 作成したHCP Terraformの設定をGitHubを使い自己管理させる
なお、Terraformを使った設定では、GitHub AppのインストールなどのGitHubとHCP Terraformの初回連携設定は行えません。そのため、HCP TerraformとHCP Terraformを自己管理するGitHubリポジトリとの連携が完了していることを前提としています。
また、HCP TerraformをTerraformで自己管理する際、Terraformを実行するWorkspaceが動いている必要があります。そのため、始めにHCP Terraformをローカル端末よりTerraformで作成し、その後TerraformコードをGitHubに上げ、HCP Terraformを自己管理する順で構築していきます。
設定順の詳細は以下の通りです。
- プロバイダーの設定
- Organizatonの設定
- Projectの設定
- Workspaceの設定
- terraformコマンドの実行
- HCP Terraformの設定を自己管理させる
1. プロバイダーの設定
HCP TerraformをTerraformで管理するには、一般的なクラウドを管理するとき同様にプロバイダーの設定が必要です。"概要"の章でも説明したように、プロバイダーはHashiCorp公式のhashicorp/tfeで管理します。以下のようにversions.tfを設定してください。
terraform {
required_version = ">= 1.8.5"
required_providers {
tfe = {
version = ">= 0.72"
source = "hashicorp/tfe"
}
}
}
provider "tfe" {
token = "{HCP Terraformのユーザートークン}"
}
ここで、HCP Terraformのユーザートークンは以下のように設定してください。
- HCP Terraformの画面右上より、"Account settings"を押下する
- 遷移後画面の左欄より"Tokens"を選択し、その後画面右上の"Create an API token"を押下します
- ポップアップした画面の内、"Description"で名前を、"Expiration"でトークンの有効期限を設定した後に、"Generate token"を押下します
- 作成したトークンの番号が表示されるため、これをコピーします(番号を確認できるのはこのタイミングだけですので、コピーすることを忘れないでください)
ここではprovider "tfe"のtokenは説明のために直接書いていますが、tokenの項目を削除し、環境変数にTFE_TOKENを渡すことを推奨します。また、直接記載した場合は、後述するコードをGitHubにpushする段階では必ず直接記載以外の方法で渡してください。
2. Organizatonの設定
ここでは、OrganizationをTerraformで管理する例について説明します。
以下はTerraformコードの例です。
resource "tfe_organization" "this" {
name = "tfe-test"
email = "通知に使うメールアドレス"
}
resource "tfe_variable_set" "this" {
name = "tfe-test-org"
organization = tfe_organization.this.name
global = true
}
3. Projectの設定
ここでは、ProjectをTerraformで管理する例について説明します。
以下はTerraformコードの例です。
resource "tfe_project" "this" {
organization = tfe_organization.this.name
name = "tfe-test-prj"
}
ここで、organization = tfe_organization.this.nameの部分は2. Organizatonで作ったものを指定してください。
4. WorkSpaceの設定
ここでは、WorkSpaceをTerraformで管理する例について説明します。
以下はTerraformコードの例です。
resource "tfe_workspace" "this" {
name = "tfe-test-ws"
organization = tfe_organization.this.name
project_id = tfe_project.this.id
queue_all_runs = false
working_directory = "/tfe"
vcs_repo {
identifier = "{連携させるGitHubリポジトリ(例: kato-test/kato-test-repo)}"
github_app_installation_id = "{連携させるGitHub AppのインストールID}"
}
}
なお、ここのgithub_app_installation_idで指定するGitHub AppのインストールIDは、GitHub側のインストールIDではなく、HCP Terraform側のインストールIDであることに注意してください。このインストールIDは以下のコマンド実行で確認してください。
$ export TFC_TOKEN={HCP Terraformのユーザートークン}
$ curl -s \
-H "Authorization: Bearer ${TFC_TOKEN}" \
-H "Content-Type: application/vnd.api+json" \
https://app.terraform.io/api/v2/github-app/installations \
| jq
{
"data": [
{
"id": "ghain-AAAAAAAAAAAAAAAA", # これがインストールIDです
"type": "github-app-installations",
"attributes": {
"name": "test-test",
~~~
}
}
]
}
5. terraformコマンドの実行
先ほど作成したOrganization、Project、WorkSpaceを設定した.tfファイルがあるディレクトリで、以下のterraformコマンドを実行してください。その後、HCP Terraformに移動し、設定した各種機能が作成されていることを確認してください。
terraform init
terraform plan
terraform apply
6. HCP Terraformの設定を自己管理させる
以上により、HCP TerraformをTerraformコードを使い作成できました。次に、HCP Terraformを自己管理していきます。設定は以下の手順で行います。
1. HCP TerraformのVariableの設定
先ほど作成したHCP Terraformの「Variable」に以下の変数設定を行います。これは、先ほど.tfファイルで設定したものと同じものを記述してください。なお、Organization、Project、WorkSpaceのどこに作っても問題ありませんが、共通の設定ですのでOrganizationの「Variable Sets」に作ることを推奨します。また、全てにおいてSensitiveの設定をすることを忘れないでください。
- e_mail
- Category: terraform
- Value: 通知に使うメールアドレス
- github_app_installation_id
- Category: terraform
- Value: HCP Terraform側のGitHub AppインストールID
- TF_API_TOKEN
- Category: env
- Value: HCP Terraformのユーザートークン
- vcs_repo
- Category: terraform
- Value: 連携するGitHubリポジトリ識別子
2. プロバイダーの設定の修正
前の章「1. プロバイダーの設定」で作成したプロバイダー設定について、tfstateの参照先をHCP Terraformにして自己管理するようにします。また、固定値として記載していたtokenを、Variable参照に修正します。修正は以下のように行ってください。
terraform {
required_version = ">= 1.8.5"
# 追記箇所
cloud {
organization = "{先ほどTerraformで作成したOrganization名}"
workspaces {
name = "{先ほどTerraformで作成したWorkSpace名}"
}
}
required_providers {
tfe = {
version = ">= 0.72"
source = "hashicorp/tfe"
}
}
}
provider "tfe" {
token = var.TF_API_TOKEN # 修正箇所
}
3. Organizationの設定の修正
前の章「2. Organizatonの設定」で直接記載していたemailを、Variable参照に修正します。修正は以下のように行ってください。
resource "tfe_organization" "this" {
name = "tfe-test"
email = var.e_mail # 修正箇所
}
resource "tfe_variable_set" "this" {
name = "tfe-test-org"
organization = tfe_organization.this.name
global = true
}
4. Projectの設定の修正について
Projectには修正箇所がありません。
5. Workspaceの設定の修正
前の章「4. WorkSpaceの設定」で直接記載していたVCS連携情報を、Variable参照に修正します。修正は以下のように行ってください。
resource "tfe_workspace" "this" {
name = "tfe-test-ws"
organization = tfe_organization.this.name
project_id = tfe_project.this.id
queue_all_runs = false
working_directory = "/tfe"
vcs_repo {
identifier = var.vcs_repo # 修正箇所
github_app_installation_id = var.github_app_installation_id # 修正箇所
}
}
6. 変数定義の追加
上記の参照先となる変数をvariables.tf等に定義します。定義は以下のように行ってください。
variable "e_mail" {
type = string
}
variable "github_app_installation_id" {
type = string
}
variable "TF_API_TOKEN" {
type = string
}
variable "vcs_repo" {
type = string
}
7. terraformコマンドの実行
terraform init -migrate-stateを実行して、ローカルのtfstateをHCP Terraformに移してください。その後、HCP Terraformに移動し、"{先ほど作成したOrganization} > Workspaces > {先ほど作成したWorkspaces} > States"に"triggered from Terraform"となっているステートがあることを確認してください。
8. GitHubに上げる
以上の修正・コマンド実行を行った後、HCP Terraformと連携しているGitHubに修正したファイルを上げてください。その後、Workspaceの"Runs"でGitHubに上げたファイル群に対してplan/applyを実行し、No changesとなることを確認してください。
既存UI設定をTerraform管理へ移行する手順
すでにUIで作ったWorkspace等を、terraform importコマンドにより後からTerraform管理に載せることもできます。やり方は以下の通りです。
- Terraformコードに対象リソースの
resource定義を追加する - 以下のように
terraform importコマンドで既存リソースをstateに取り込む
terraform import tfe_workspace.test "{Workspaceが所属しているOrganization}/{Workspace名}"
-
terraform planで差分を確認し、必要ならコードを調整する
最後に
HCP TerraformをTerraformで管理することで、UI操作中心の運用に比べて、設定変更の再現性と運用品質を大きく高められます。以下はその利点です。
- 変更履歴をGitで一元管理でき、いつ・誰が・なぜ変えたかを追跡しやすい
- PRレビューを前提にした運用により、設定ミスや権限の強い変更を事前に検知しやすい
- Organization / Project / Workspaceの設定をコードで共通化でき、環境間の設定ドリフトを抑制できる
- Tokenや外部連携情報をVariableで扱うことで、秘匿情報の安全な運用と継続的な保守を両立しやすい
まずは小さな構成から始め、段階的な適用を組み合わせながら管理範囲を広げることで、無理なく安定したIaC運用へ移行できます。