Module は Terraform 構成を小さな単位に分割し、再利用可能なインターフェイスとして公開する仕組み。チーム規模が大きくなるほど、モジュール境界とバージョン管理の設計が結果の安定性を左右する。
Associate 試験では、module ブロックの構文、source の種類、version の意味、count/for_each/depends_on の可用性、Provider 継承とエイリアスの扱いが頻出。ここでは実務の作法と合わせて、誤答しやすいポイントを重点的に整理する。
Module は「入力(variables)」「処理(リソース定義)」「出力(outputs)」をひとまとまりにし、呼び出し側から内部実装を隠す。これにより、同じ構成の繰り返しをなくし、変更影響範囲を小さく保てる。
抽象化の鍵は「インターフェイスの明確化」と「バージョンによる契約」。変数の型・既定値・検証、出力の最小化、意味のあるセマンティックバージョニングを徹底する。
Root と子 Module の関係(入出力と Provider 継承)
module ブロックは source に取得元を指定し、必要な入力を渡す。Terraform 0.13 以降は module に対しても count/for_each/depends_on が使える。version 引数は Terraform Registry 由来のモジュールにのみ有効で、Git やローカルパスでは無視される点に注意。
再現性の高い実行には、Registry では version をセマンティックバージョニングで固定し、Git では ref(タグ/ハッシュ)を用いる。ローカルパスは開発時に便利だが、チーム配布時は Registry や Git を使うと依存が明示化される。
module 呼び出しの具体例(Registry / Git / ローカル、for_each・depends_on 併用)
# Registry 由来(version が有効)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0" # セマンティックバージョニングでのピン留め
name = var.project
cidr = var.vpc_cidr
enable_dns_hostnames = true
}
# Git 由来(version は無効。ref で固定)
module "webapp" {
source = "github.com/acme/terraform-webapp?ref=v1.2.3"
name = "webapp"
}
# ローカルパス(開発・単体テスト向け)
module "sg" {
source = "./modules/sg"
name = "default-sg"
}
# for_each と depends_on を module に適用(0.13+)
module "sg_by_tier" {
source = "./modules/sg"
for_each = toset(["app", "db"])
name = each.key
depends_on = [module.vpc] # VPC 作成完了を待つ
}入力(variables)は型、既定値、validation を明示し、受け付ける値の範囲を狭める。特に構造体(object)での受け渡しは、将来の互換性を意識して必須/任意フィールドを分ける。
出力(outputs)は本当に必要な最小限にする。秘匿情報は sensitive = true を付与し、出力経由での漏洩を防ぐ。locals は内部の命名や計算を整理するために使い、外部契約には含めない。
Provider の設定は通常 Root module で行い、子 module はそれを継承する。1 つの provider に複数設定(エイリアス)を持たせる場合、module ブロックの providers マップで明示的に渡す。
子 module 側では required_providers で利用する provider を宣言するが、provider ブロックによる具体設定は持たないのが原則。こうすると呼び出し側の制御が効き、環境間差分(リージョン/アカウント)を簡潔に切り替えられる。
source の選択は再現性、審査、配布のしやすさに直結する。Registry は version によるピン留めが可能で最も扱いやすい。Git は ref による固定で柔軟だがブランチ参照は再現性を損なう。ローカルは開発補助として使い、本番配布では避ける。
| 取得元 | source 記法の例 | バージョン固定方法 | 再現性/キャッシュ |
|---|---|---|---|
| Terraform Registry | terraform-aws-modules/vpc/aws | version = "~> 5.0"(module ブロックで有効) | 高い(プロキシ/ミラー対応可) |
| Git(GitHub/GitLab 等) | github.com/acme/app?ref=v1.2.3 | ref にタグ/ハッシュを指定(version は無効) | 中〜高(ref の固定次第) |
| ローカルパス/アーカイブ | ./modules/network または ./pkg.zip//modules/vpc | 固定不可(呼び出し側のファイルそのもの) | 低(実行環境差の影響大) |
試験では module の source と version の関係、module ブロックで使えるメタ引数、Provider 継承と alias のマッピングが狙われやすい。実務ではセマンティックバージョニングと入出力の厳格化が品質を左右する。
依存の再現性(version/ref の固定)を怠ると、init のたびに差分が出て計画の信頼性が落ちる。ブランチ参照や暗黙の provider 参照は避ける。
Associate
問題 1
次のうち、module ブロックの version 引数が有効に解釈されるケースはどれか?
正解: A
version 引数は Terraform Registry から取得するモジュールにのみ適用される。Git/HTTP/S3/ローカルなど Registry 以外の source では version は無視され、Git は ref、HTTP/S3 は URL での固定が必要。
どのタイミングで Module 化すべきですか?
同じ構成を2–3回以上繰り返す見込みがある、もしくは統制(タグ/暗号化/ログ)を強制したいとき。まずは小さく分け、入力(variables)と出力(outputs)を明示してから社内共有へ展開すると失敗しにくい。
Module のバージョンはどう固定・更新しますか?
Registry では module ブロックの version に ~> などの範囲指定でピン留めし、更新時は terraform init -upgrade で引き上げる。Git は ref にタグやコミットハッシュを指定。破壊的変更はメジャーバージョンで受け取り、検証環境で plan 差分を確認してから本番に適用する。
子 Module で provider 設定を書いてもよいですか?
原則避けるべき。子 Module では required_providers で必要なプロバイダを宣言するに留め、設定(credentials、region など)は Root 側で行い、必要に応じて providers マップで alias を明示的に渡す。このほうが環境差分の切り替えと監査が容易。
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を用いた既存リソース参照の基本、選択基準、評価順序、...