ハブ記事: Terraform モジュール 完全ガイド →
設計・配布・運用まで Terraform モジュールの全体像を一望できるハブ記事
Terraformのモジュールはsourceで取得元を指定し、レジストリ経由の場合のみversionで制約できます。Git等のURLソースではversionは無効で、タグやコミットをrefで固定します。
この記事は、実務で壊れないアップグレードを実現するための最小原則と、資格試験で問われやすいポイントを一気通貫でまとめました。
moduleブロックではsourceが必須です。レジストリ経由のモジュールのみversion引数でバージョン制約が使えます。Gitやローカルパスなどレジストリ以外のソースではversionは使えず、初期化時にエラーになります。
GitなどURLベースのソースでは、refクエリでタグ名、ブランチ、またはコミットSHAを指定して固定します。再現性重視ならタグまたはコミットSHAでの固定が基本です。
モジュール解決の流れ
module "x" {
source + version? terraform init
| | |
| | 依存解決エンジン
| | v
+--> ソースアドレス ----> 取得元判定
| |
| +--> レジストリ: version制約を解決し最新版選択
| |
| +--> Git/HTTP等: refがあればそのタグ/コミットを取得
v (なければデフォルトブランチ)
.terraform/modules に展開
レジストリ経由の基本例
terraform {
required_version = ">= 1.3"
}
module "consul" {
source = "hashicorp/consul/aws" # レジストリアドレス
version = "~> 0.10" # 0.10.x に固定(将来の0.11系は除外)
}
試験でも実務でも混同しやすいのが、レジストリとGitの指定差分です。versionが使えるのはレジストリのみ。Gitではref=でタグやコミットを指定します。ローカルパスやHTTPアーカイブもversionは使えません。
再現性の確保が最優先です。本番ではブランチ固定(mainやmaster)ではなく、タグやコミットSHAで固定しましょう。
| ソース種別 | バージョン指定の方法 | 記述例 | 注意点 |
|---|---|---|---|
| レジストリ(公開/私有) | version に制約式 | source = "app.terraform.io/acme/network/aws" version = "~> 2.4" | init -upgradeで最新許容版を解決。セマンティックバージョニング |
| Git(タグ) | sourceのref=タグ | source = "git::https://github.com/org/terraform-modules.git//vpc?ref=v1.2.3" | 範囲指定は不可。タグ運用の規律が必要 |
| Git(コミットSHA) | sourceのref=SHA | source = "git::ssh://[email protected]/org/mods.git//eks?ref=9f2c0ab" | 完全固定で再現性が高いが、人に優しくない |
| ローカルパス | なし | source = "../modules/alb" | ローカル変更が即時反映。CI/CDや複数環境では非推奨 |
| HTTPアーカイブ | なし | source = "https://example.com/mods/vpc-1.2.3.zip" | 改ざん防止にチェックサム管理を推奨 |
Gitタグでの固定例とサブディレクトリ指定
module "vpc" {
source = "git::https://github.com/org/terraform-modules.git//network/vpc?ref=v1.2.3"
}
module "eks" {
source = "git::ssh://[email protected]/org/iac.git//modules/eks?ref=9f2c0abd1"
}
Terraform Cloud/Enterpriseのプライベートモジュールレジストリでは、sourceに app.terraform.io/<org>/<name>/<provider> を使い、versionで制約します。VCS上のリリースタグ(SemVer)を登録し、利用側はversion制約で受け取ります。
初回はterraform loginで認証を行い、init時にモジュールが解決されます。アップグレードはコード上のversion制約を保ちつつ、terraform init -upgradeで許容範囲の最新に更新します。
私有レジストリ利用例
module "network" {
source = "app.terraform.io/acme/network/aws"
version = "~> 2.4" # 2.4.x を許容
}
# 初回認証: terraform login
レジストリ経由ではSemVer準拠の制約を使います。~> 演算子は「左から2成分を固定する」慣用で、~> 1.2 は >= 1.2.0 かつ < 1.3.0 を意味します。プロダクションはパッチだけ許容、ステージングはマイナーまで許容など、環境別に設計できます。
Gitソースには範囲指定はなく、タグやコミットで明示的に更新します。自動更新を期待するならレジストリへの登録とversion制約を選びます。
制約式の具体例
module "web" {
source = "app.terraform.io/acme/web/aws"
version = "~> 1.8" # 1.8.x
}
module "batch" {
source = "app.terraform.io/acme/batch/aws"
version = ">= 2.3, < 3.0" # 複合条件
}
# Gitは範囲不可。タグ/コミットで固定
module "ops" {
source = "git::https://github.com/acme/ops-mods.git//alerts?ref=v0.9.5"
}
レジストリ経由のモジュールは、既にダウンロード済みであればinitは同じ版を再利用します。許容範囲内で新しい版に上げるには terraform init -upgrade を実行します。Gitソースはコード中のrefを書き換えない限り更新されません。
依存のロックファイル(.terraform.lock.hcl)はプロバイダ専用で、モジュールには適用されません。再現性はversion制約(Gitならタグ/コミット固定)と、.terraformディレクトリの再作成で担保します。
CIジョブ例
# Bash例
set -euo pipefail
rm -rf .terraform/ # クリーンに再現
terraform init -upgrade
terraform validate
terraform plan -out=tfplan
Gitソースでversionを指定してしまう、という誤りは試験でも頻出です。versionはレジストリ専用で、Gitはrefです。また、mainなどのブランチ固定は常に変動するため本番では避けます。
providerのversionピン留めとmoduleのversionピン留めを混同しないこと。required_providersはプロバイダのみ、moduleのversionはレジストリモジュールのみです。
悪い例と良い例
# 悪い例: Gitにversionを書いている
module "bad" {
source = "git::https://github.com/org/mods.git//vpc"
version = "~> 1.2" # ← エラー: versionは無効
}
# 良い例: Gitタグで固定
module "good_git" {
source = "git::https://github.com/org/mods.git//vpc?ref=v1.2.3"
}
# 良い例: レジストリで範囲指定
module "good_registry" {
source = "app.terraform.io/acme/vpc/aws"
version = "~> 1.2"
}
Associate / Pro
問題 1
GitHub上のモジュールを利用し、本番で再現性を確保したい。推奨される指定はどれか。
正解: B
versionはレジストリモジュール専用で、Gitソースでは無効。再現性を確保するにはタグ(またはコミットSHA)をrefで固定する。ローカルパスは共有・再現性に乏しく、main固定は変動が激しく本番に不向き。
モジュールにも.providerのようなロックファイルはありますか?
いいえ。.terraform.lock.hclはプロバイダ用のロックです。モジュールはversion制約(レジストリ)かref固定(Git)で再現性を確保します。
レジストリでタグの先頭にvを付けても大丈夫ですか?
一般的なSemVerのvプレフィックス(v1.2.3)はサポートされます。Terraform Cloud/Enterpriseの私有レジストリでもSemVer準拠のタグを推奨します。
initだけで最新の許容バージョンに自動で上がりますか?
いいえ。既に取得済みの場合は同じ版を再利用します。許容範囲内の最新版に更新するには terraform init -upgrade を実行してください。Gitソースはrefを書き換えない限り更新されません。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...