Terraform Associate 004 #6 モジュール — ソース指定、バージョン固定、入出力の文法

読了 4分

モジュール領域は範囲が狭い代わりに問題密度が高い領域です。ソース指定の文法、version が効く場合と効かない場合、出力へのアクセス文法という 3 つのかたまりが繰り返し出ます。基礎 #8の内容を試験の角度で圧縮します。

定義 — すべての設定はすでにモジュールの中 #

試験が期待する定義はこうです。モジュールは一緒に使われるリソースをまとめた設定ファイルのコンテナ(ディレクトリ)で、Terraform を実行するディレクトリがルートモジュール、module ブロックで呼び込むものが子モジュールです。「モジュールを使わない設定」という表現は成立しません。どんな設定もルートモジュールだからです。このフレーミング(「すべての設定は最低 1 つのモジュールを持つ」)がそのまま出題されます。

ソース指定 — 3 つの方式 #

module ブロックの source は、文字列の形式によって場所が解釈されます。

main.tf
# 1. レジストリ: <ネームスペース>/<名前>/<プロバイダー> 形式
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 6.0"
}

# 2. Git: プレフィックスで判別、ref でバージョン指定
module "app" {
  source = "git::https://github.com/my-org/tf-app.git?ref=v1.2.0"
}

# 3. ローカルパス: ./ または ../ で始まる
module "network" {
  source = "../modules/network"
}

試験ポイントは version 引数が動作する条件です。version はレジストリソースでのみ有効です。Git ソースのバージョンは URL の ref クエリで指定し、ローカルパスにはバージョンの概念がなく、その時点のファイルで決まります。「ローカルモジュールに version を指定する」という選択肢は誤答で、レジストリモジュールで version を省略すると最新を取得して再現性が壊れること(基礎 #8の「version 固定は必須」)が正答方向です。そしてモジュールを追加、変更したら init が必要という点も、ここに束ねられる定番です。

入力と出力 — モジュールのインターフェース #

  • 入力: 子モジュールが宣言した variable に、module ブロックの引数として値を渡します。
  • 出力: 子モジュールが宣言した output だけを module.名前.出力 の形で読めます。
main.tf
module "network" {
  source   = "../modules/network"
  vpc_cidr = "10.0.0.0/16"          # 入力: モジュールの variable へ
}

resource "aws_instance" "web" {
  subnet_id = module.network.private_subnet_id   # 出力: module.名前.出力
}

ここで試験が狙う原則がカプセル化です。呼び出し側は、子モジュールの中のリソースに直接アクセスできません。module.network.aws_subnet.private.id のようなアドレスは成立せず、モジュールが output として公開した値だけを読めます。「モジュールの中の値が必要なのに output がない」という場合の答えは、モジュールに output を追加することです。逆方向(モジュールが呼び出し側の値を読むこと)も variable を通じてのみ可能です。

パブリックレジストリ — verified 表示とドキュメント #

Terraform Registry のパブリックモジュールに関する出題ポイントは、軽めの 2 つです。HashiCorp がパートナーを検証したモジュールには verified 表示が付くこと、そしてレジストリのページが入力、出力、依存関係のドキュメントと使用例を提供するので、モジュールの評価はそのドキュメントで行うことです。「verified でないモジュールは使えない」という趣旨の選択肢は誤答です。表示は信頼のための参考情報であって、使用の制限ではありません。

モジュール設計の常識問題 #

設計原則を問う問題の正答方向も、基礎 #8の基準と一致します。一緒に作られ一緒に消えるリソースのまとまりをモジュールにし、リソース 1 つを包んだだけの薄いラッパーモジュールは避け、入力は必要なぶんだけ開けてインターフェースを狭く保ちます。トラックで実習した実践 #9の modules と envs の構造がこの原則の実物例なので、あの構造を思い出せば設計問題の大半は解けます。

まとめ #

今回扱った内容です。

  • 実行ディレクトリがルートモジュール、module ブロックで呼ぶものが子モジュールで、すべての設定は最低 1 つのモジュールです
  • ソースはレジストリ形式、git:: プレフィックス、./ と ../ のローカルパスで判別されます
  • version 引数はレジストリソース専用です。Git は ref、ローカルにはバージョンの概念がありません。モジュール変更後は init です
  • モジュールはカプセル化されます。中のリソースへの直接アクセスは不可で、output として公開した値だけを module.名前.出力 の形で読みます
  • verified 表示は信頼のための参考情報であって、使用の制限ではありません

次回(#7 設定の記述)では、変数と出力、関数と式、そして 004 で強化されたカスタム条件(validation、precondition、postcondition)を扱います。トラックで浅めに通り過ぎた部分を補強する回です。

X