Terraform

Terraform Modules の概要: 再利用と抽象化を正しく使う

2026-04-19
NicheeLab編集部

Module は Terraform 構成を小さな単位に分割し、再利用可能なインターフェイスとして公開する仕組み。チーム規模が大きくなるほど、モジュール境界とバージョン管理の設計が結果の安定性を左右する。

Associate 試験では、module ブロックの構文、source の種類、version の意味、count/for_each/depends_on の可用性、Provider 継承とエイリアスの扱いが頻出。ここでは実務の作法と合わせて、誤答しやすいポイントを重点的に整理する。

なぜ Module を使うのか: 再利用と抽象化

Module は「入力(variables)」「処理(リソース定義)」「出力(outputs)」をひとまとまりにし、呼び出し側から内部実装を隠す。これにより、同じ構成の繰り返しをなくし、変更影響範囲を小さく保てる。

抽象化の鍵は「インターフェイスの明確化」と「バージョンによる契約」。変数の型・既定値・検証、出力の最小化、意味のあるセマンティックバージョニングを徹底する。

  • 同一パターンの横展開(例: VPC、セキュリティグループ、標準監視)
  • 共通ガードレールの強制(タグ、暗号化、ログ出力)
  • 変更に強い境界設定(モジュール外部への影響を限定)

Root と子 Module の関係(入出力と Provider 継承)

Root modulemain.tf / providers.tf / vars.tfmodule networkmodule.network.*module computemodule.compute.*module dbmodule.db.*...Root module から子 module を呼び出し、outputs は Root に集約される

モジュール呼び出しの基本構文とバージョン管理

module ブロックは source に取得元を指定し、必要な入力を渡す。Terraform 0.13 以降は module に対しても count/for_each/depends_on が使える。version 引数は Terraform Registry 由来のモジュールにのみ有効で、Git やローカルパスでは無視される点に注意。

再現性の高い実行には、Registry では version をセマンティックバージョニングで固定し、Git では ref(タグ/ハッシュ)を用いる。ローカルパスは開発時に便利だが、チーム配布時は Registry や Git を使うと依存が明示化される。

  • version は Registry でのみ有効。Git/HTTP/S3/ローカルでは ref 等で固定する
  • count/for_each/depends_on は module ブロックでも利用可(0.13+)
  • module の入出力は型と既定値、validation で契約を明確化

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 作成完了を待つ
}

入力変数・出力・locals: インターフェイスを締める

入力(variables)は型、既定値、validation を明示し、受け付ける値の範囲を狭める。特に構造体(object)での受け渡しは、将来の互換性を意識して必須/任意フィールドを分ける。

出力(outputs)は本当に必要な最小限にする。秘匿情報は sensitive = true を付与し、出力経由での漏洩を防ぐ。locals は内部の命名や計算を整理するために使い、外部契約には含めない。

  • variables: type、default、validation(error_message)で不正入力を弾く
  • outputs: 最小限・sensitive を活用。内部 ID の垂れ流し禁止
  • locals: 外部に露出しない内部表現の統一に有効
  • 破壊的変更はメジャーバージョンを上げ、CHANGELOG で明記

Provider と Module の関係(継承とエイリアス)

Provider の設定は通常 Root module で行い、子 module はそれを継承する。1 つの provider に複数設定(エイリアス)を持たせる場合、module ブロックの providers マップで明示的に渡す。

子 module 側では required_providers で利用する provider を宣言するが、provider ブロックによる具体設定は持たないのが原則。こうすると呼び出し側の制御が効き、環境間差分(リージョン/アカウント)を簡潔に切り替えられる。

  • Root で provider 設定、子は継承。必要なら providers でエイリアスマッピング
  • 子 module は required_providers の宣言のみ(設定は Root)
  • 複数アカウント/リージョン対応は alias を活用し、意図しない provider 参照を防ぐ

Module 取得元の比較: Registry / Git / ローカル

source の選択は再現性、審査、配布のしやすさに直結する。Registry は version によるピン留めが可能で最も扱いやすい。Git は ref による固定で柔軟だがブランチ参照は再現性を損なう。ローカルは開発補助として使い、本番配布では避ける。

  • 長期運用は Registry かタグ付き Git を推奨
  • チーム内審査や利用制限にはプライベート Registry も選択肢
  • ブランチ参照(ref=main 等)はドリフトの原因
取得元source 記法の例バージョン固定方法再現性/キャッシュ
Terraform Registryterraform-aws-modules/vpc/awsversion = "~> 5.0"(module ブロックで有効)高い(プロキシ/ミラー対応可)
Git(GitHub/GitLab 等)github.com/acme/app?ref=v1.2.3ref にタグ/ハッシュを指定(version は無効)中〜高(ref の固定次第)
ローカルパス/アーカイブ./modules/network または ./pkg.zip//modules/vpc固定不可(呼び出し側のファイルそのもの)低(実行環境差の影響大)

Associate 試験対策と実務の落とし穴

試験では module の source と version の関係、module ブロックで使えるメタ引数、Provider 継承と alias のマッピングが狙われやすい。実務ではセマンティックバージョニングと入出力の厳格化が品質を左右する。

依存の再現性(version/ref の固定)を怠ると、init のたびに差分が出て計画の信頼性が落ちる。ブランチ参照や暗黙の provider 参照は避ける。

  • 覚える: module の source 種別、version は Registry のみ、Git は ref
  • 覚える: module に count/for_each/depends_on が使える(0.13+)
  • 実務: 破壊的変更は major を上げ、更新は terraform init -upgrade で段階的に検証
  • 実務: outputs の最小化・sensitive 指定、内部 ID の露出禁止
  • 実務: 子 module で provider 設定を持たない(required_providers の宣言のみ)

問題で確認

Associate

問題 1

次のうち、module ブロックの version 引数が有効に解釈されるケースはどれか?

  1. Terraform Registry に公開されたモジュールを source に指定した場合
  2. GitHub のモジュールを source に指定し、version と ref を同時に指定した場合
  3. ローカルパス(./modules/vpc)を source に指定した場合
  4. S3 上のアーカイブ(s3::https://.../vpc.zip)を source に指定した場合

正解: 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 を明示的に渡す。このほうが環境差分の切り替えと監査が容易。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.