【実務・中級編】Terraform Registryのプライベートモジュール開発:GitHub Packagesを用いた社内共通インフラ資産の共有基盤構築 – インフラ構成管理(IaC)活用バイブル

Terraformモジュールは「コピペ」するな:GitHub Packagesで築く、鉄壁の社内共有基盤

Terraformモジュールの管理で、いまだに`git clone`やローカルパス参照をしていませんか?
「あのプロジェクトのVPCモジュール、どこまで修正したんだっけ?」といった会話が聞こえてくる時点で、その組織はIaCの迷宮に迷い込んでいます。

真のSREは、インフラを「コード」ではなく「プロダクト」として扱い、Registryという名の流通網に乗せる。今日は、Terraform Registryのプライベート対応をGitHub Packagesで構築し、組織のデリバリー速度を劇的に跳ね上げる「現場の作法」を伝授します。

—

1. なぜ「GitHub Packages」を選ぶのか

多くの組織がTerraform Cloud/Enterpriseのレジストリを利用しますが、コストや権限管理の観点からGitHub Packages(特にGitHub Container Registry – GHCR)を選択するケースが増えています。

選定の極意:

  • 認証の統一: GitHub Actionsの`GITHUB_TOKEN`で全て完結する。
  • 権限管理: GitHubのOrganization/Team権限に完全準拠。
  • 不変性: OCIイメージとして管理されるため、バージョニングが確実。

—

2. 実践:プライベートRegistryの構築手順

Terraformは、`terraform init`時にTerraform Registryプロトコルを喋るサーバーにアクセスします。GitHub Packagesをこれに応答させるには、OCIレジストリとして公開するのが最短ルートです。

ステップ1:モジュールのパッケージ化(`Makefile`の活用)

モジュールを公開する際は、必ず`terragrunt`や`terraform-config-inspect`と組み合わせ、`version`を厳密に管理します。

Makefileの自動化:セマンティックバージョニングを強制する
VERSION := $(shell git describe –tags –always)

.PHONY: publish
publish:
# モジュールをOCIアーティファクトとしてパッケージングしGHCRへプッシュ
# terraform-registry-proxy等のOSSを利用するのが最も現実的
docker build -t ghcr.io/your-org/terraform-modules/vpc:$(VERSION) .
docker push ghcr.io/your-org/terraform-modules/vpc:$(VERSION)

ステップ2:認証設定(`.terraformrc`の神設定)

開発者のローカル環境で最も躓くのが認証です。`~/.terraformrc` (または `~/.terraform.d/plugins.json`) に以下を記述し、認証情報を切り分けます。

~/.terraformrc
credentials “ghcr.io” {
token = “ghp_xxxxxx” # 環境変数 TF_TOKEN_ghcr_io を使うのがベスト
}

—

3. チーム開発を加速させる「極限の知見」

神プラグイン & 設定

Terraformを書く際、以下の環境構築ができていないなら、今すぐ修正してください。

1. `terraform-ls` (Language Server): これなしでの開発は、地図なしで密林を歩くようなもの。VS Codeの`hashicorp.terraform`拡張機能は必須。
2. `tflint`: ルールセットを`.tflint.hcl`で全社配布し、CIで強制的にFailさせる。「なぜダメなのか」をコードレビューで説明する時間をゼロにします。
3. `tfsec` / `terrascan`: セキュリティは開発の初期段階で排除する。

隠れたキーボードショートカット (VS Code):

  • `Ctrl + Shift + P` -> `Terraform: Format`: 保存時に実行されるよう設定済みか?(`”editor.formatOnSave”: true`)
  • `Ctrl + Click`: モジュール定義へのジャンプ。これができない構成は、依存関係が破綻している証拠。

—

4. モジュール設計のベストプラクティス(YAML管理)

共通基盤として提供する際、`variables.tf`が肥大化するのは悪手です。設定値の複雑な組み合わせは、JSON/YAMLスキーマでバリデーションをかけるのがプロのやり方です。

推奨するディレクトリ構成:

.
├── main.tf
├── variables.tf
├── outputs.tf
├── examples/ # 必須!利用者のためのコピー&ペースト可能なサンプル
├── modules/ # サブモジュール群
└── schema.json # 構造化された入力値の定義

実用的なバリデーション(`variables.tf`):

variable “instance_type” {
type = string
description = “EC2インスタンスタイプ”

# 現場で震えるほど重要な「動的なバリデーション」
validation {
condition = can(regex(“^(t3|m5|c5)\\.”, var.instance_type))
error_message = “許可されていないインスタンスタイプです。コスト管理ポリシーに従ってください。”
}
}

—

5. 最後に:テックリードからの提言

GitHub Packagesをレジストリとして利用することは、単なる「共有基盤」を作る作業ではありません。「チームがインフラの書き方を学ぶための教科書」を公開する行為です。

1. ドキュメントは `README.md` ではなく `examples/` で語れ。
2. モジュールは「疎結合」に保て。 複数のリソースを詰め込んだ巨大モジュールは、ただの「負債」です。
3. CI/CDを通さない変更は「存在しないもの」として扱え。

この基盤を構築すれば、新メンバーが参画したその日に、彼らは「社内の標準的なVPC」を一行のコードで呼び出せるようになります。その瞬間こそが、エンジニアリング組織がスケールする瞬間です。

さあ、今すぐレポジトリを整理し、Registryを立ち上げましょう。コードが標準化されれば、世界はもっとシンプルになるはずです。

タイトルとURLをコピーしました