Terraform の input variable は、モジュールの「公開インターフェイス」です。丁寧に設計すると再利用性が上がり、現場の事故(型不一致や値の取り違え)も避けられます。一方で、型や優先順位の理解が曖昧だと、意図しない値が適用されたり、秘密情報が出力に混ざるなどのトラブルが起きがちです。
ここでは、公式ドキュメントの挙動に沿って、variable ブロックの型設計、検証、機密扱い、値の優先順位、モジュール境界での渡し方を整理します。Terraform Associate 試験で頻出の観点も示しながら、手元のコードにすぐ取り入れられる実装パターンを提示します。
variable ブロックは、モジュールに与える外部入力の定義です。名前、型、説明、デフォルト、検証、機密フラグなどを宣言します。デフォルトが無い変数は「必須入力」となり、計画・適用時に値の供給が必要です。
Terraform は宣言的であり、変数は「状態を持つ」のではなく「評価時に解決」されます。したがって、どこから値が供給され、どの値が最終的に採用されるのか(優先順位)を正しく理解することが、設計上の出発点になります。
型は variable 設計の中核です。プリミティブ(string/number/bool)、コレクション(list/set/map)、構造(object/tuple)を使い分けることで、入力の曖昧さを排除できます。特に list と set、map と object の違いは試験でも実務でも重要です。
可能な限り「使い方に合った最も厳格な型」を選びます。後からの破壊的変更を避けるため、将来の拡張が見込まれる入力は object でスキーマ化するのが無難です。
| 型/パターン | 例 | 向いている用途・注意点・試験ポイント |
|---|---|---|
| プリミティブ | string / number / bool | 最も単純。フラグや名前、数値。bool は文字列と混同しない("true" ではなく true)。 |
| list vs set | list(string) / set(string) | 順序を保ちたいなら list。重複排除・for_each と相性が良いのは set(順序なし)。 |
| map vs object | map(string) / object({k=...}) | 自由鍵のタグ等は map。スキーマを固定して将来の破壊的変更を抑えたいなら object。 |
| tuple vs list | tuple([string, number]) | 位置と型が固定。外部入力では保守性に難。試験では『固定長・位置依存』を押さえる。 |
| any | type = any | 柔軟だが安全性低下。使うなら validation で縛る。試験では『推奨は厳格型』を意識。 |
入力の安全性と利用体験は、属性設計で大きく変わります。default を与えると optional、未指定だと required です。validation ブロックで受理範囲を明示し、エラーを早期発見しましょう。sensitive は計画出力や UI でのマスキングに効きますが、state の秘匿化ではありません(バックエンドの暗号化を別途検討)。
Terraform 1.x では nullable を指定して null の受け入れ可否を制御できます。プロバイダや言語仕様のバージョンにより細部の挙動が異なる場合があるため、チームのバージョンを固定してから導入すると安全です。
変数ブロック例: 型制約・検証・機密・null 戦略
variable "environment" {
type = string
description = "デプロイ環境: dev/stg/prod"
validation {
condition = contains(["dev", "stg", "prod"], var.environment)
error_message = "environment は dev, stg, prod のいずれかにしてください。"
}
}
variable "instance_count" {
type = number
description = "作成するインスタンス数"
default = 2
validation {
condition = var.instance_count >= 1 && var.instance_count <= 20
error_message = "instance_count は 1〜20 の範囲で指定してください。"
}
}
variable "tags" {
type = map(string)
description = "共通タグ"
default = {}
}
variable "admin_password" {
type = string
description = "管理者パスワード"
sensitive = true
}
variable "optional_domain" {
type = string
description = "省略可のカスタムドメイン。未設定なら null"
default = null
nullable = true
}
variable "network" {
type = object({
vpc_id = string
subnet_ids = list(string)
enable_public = bool
})
description = "ネットワーク設定"
}
locals {
# null や空をフォールバック
effective_tags = length(var.tags) > 0 ? var.tags : {
"managed-by" = "terraform"
}
}
resource "example_instance" "this" {
count = var.instance_count
name = "${var.environment}-app-${count.index}"
tags = local.effective_tags
# 注意: var.admin_password を平文で出力に流さない。
}
モジュールを再利用可能にする鍵は、入力インターフェイスの安定性です。関連する値は object にまとめ、利用者にとって意味のある単位で渡せるようにします。タグのような任意キー集合は map(string)、スキーマが固定の設定群は object が適します。
破壊的変更(型の変更、必須化など)はモジュールのバージョニングで管理します。required/optional の切り替えは利用者影響が大きいので、optional 化は default または null 受け入れ+locals フォールバックで進めるのが無難です。
同じ変数に複数の供給源がある場合、Terraform は決められた優先順位で最終値を選びます。より「明示的な」指定が強く、最後に解決されたものが採用されます。Associate でも頻出です。
自動読込されるファイル(terraform.tfvars、*.auto.tfvars)と、CLI で明示する -var/-var-file の違いを押さえておきましょう。環境変数 TF_VAR_name は低い優先度で、デフォルト値の上書きに使えます。
変数値の優先順位(左=低 → 右=高)
変数設計で陥りがちな落とし穴をまとめます。レビュー時のチェックリストとしても使えます。
特に any の乱用、string で真偽値を扱う、validation 未設定、sensitive の放置は典型的な事故要因です。
Associate
問題 1
変数 name に対して、variable ブロックで default="app" を定義。環境変数 TF_VAR_name=api を設定し、同じディレクトリに terraform.tfvars で name="web" を置き、さらに -var-file=env/dev.tfvars(中で name="batch")を指定して plan を実行した。最終的に適用される name はどれか。
正解: A
変数の優先順位は概ね default < 環境変数 < terraform.tfvars < *.auto.tfvars < -var-file < -var。したがって -var-file 内の name="batch" が最終的に採用される。
sensitive = true にすると state は安全になりますか?
いいえ。sensitive は計画や UI での表示をマスクするだけで、state ファイル自体を暗号化しません。バックエンド(例: Terraform Cloud、リモートバックエンドの暗号化、ストレージ側の暗号化)で保護し、output に秘密を直接流さない設計が必要です。
map(string) と object のどちらを使うべきですか?
任意キーの辞書(例: タグ)は map(string) が適します。属性名と型を固定したい設定群(例: ネットワーク設定)は object を使い、将来の拡張もスキーマで管理します。試験では『map は自由鍵、object は固定スキーマ』を押さえてください。
環境ごとの値はどう渡すのがよいですか?
環境別の tfvars を用意し、-var-file=env/dev.tfvars のように明示指定するのが実務で扱いやすく、優先順位も明確です。共通値は terraform.tfvars、個別上書きは -var または環境変数 TF_VAR_name を使う運用が分かりやすいです。
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を用いた既存リソース参照の基本、選択基準、評価順序、...