ハブ記事: Terraform モジュール 完全ガイド →
設計・配布・運用まで Terraform モジュールの全体像を一望できるハブ記事
Terraform の outputs は、モジュール間で値を受け渡しし、実行後に必要な情報を表示するための公式メカニズムです。Associate レベルでも、宣言方法、参照方法、sensitive の挙動、評価順序の制御あたりが頻出です。
この記事では、実務で壊れにくい outputs 設計と、試験で問われやすい観点をまとめます。バージョン依存の挙動に触れる場合は、現行の安定仕様に限って扱います。
output ブロックはモジュール内で計算した値を外に公開します。親モジュールは module.<子>.output_name で参照できます。ルートモジュールの outputs は terraform apply 後に表示され、terraform output コマンドで再表示できます。
output には value(必須)、description(任意)、sensitive(任意)、そして必要に応じて depends_on(評価順序の明示)が指定できます。値は型推論され、複合型(オブジェクトやマップ)も返せます。
最小構成の output(子と親)
# 子モジュール: modules/network/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
description = "作成した VPC の ID"
}
# 親モジュール: main.tf
module "network" {
source = "./modules/network"
}
output "network_vpc_id" {
value = module.network.vpc_id
}複数モジュールを配線する際は、子の outputs を親が受け取り、必要に応じて親でも再出力します。ワークスペース間で値を渡す場合は terraform_remote_state データソースを用いますが、疎結合に留め、契約(スキーマ)を安定させることが重要です。
出力値は apply 完了後に確定します。plan 時点で unknown の値は依存の連鎖により親でも unknown になり得ます。unknown を前提にしても壊れないよう、条件分岐や null 合体などで防御的に設計します。
親モジュールと子モジュールの出力の流れ
親で子の出力を再出力/remote_state で他ワークスペースの出力を参照
# 親で子の出力を参照し、再出力
module "web" { source = "./modules/web" }
module "svc" {
source = "./modules/service"
a_id = module.web.a_id
}
output "alb_dns" {
value = module.web.alb_dns
}
output "service_url" {
value = module.svc.service_url
}
# 他ワークスペースの出力を読む(Terraform Cloud/Enterprise の例)
data "terraform_remote_state" "network" {
backend = "remote"
config = {
organization = "acme"
workspaces = { name = "network-prod" }
}
}
# 取得した出力の活用例
module "app" {
source = "./modules/app"
vpc_id = data.terraform_remote_state.network.outputs.vpc_id
}出力の型を安定させると、親側の参照が壊れにくくなります。特に for_each で複数作成した子モジュールの値を集約する場合、マップやリストの並び順・キーを明確にします。
順序が未定義な集合は sort() や toset()/tolist() で明示化し、オブジェクトは tomap() でキーを固定します。将来のスキーマ拡張を見越し、オブジェクト出力には description で契約を記述しておくと運用が楽です。
for_each した子モジュールの出力を安定化して返す例
# 子モジュール群(仮)
module "subnet" {
source = "./modules/subnet"
for_each = {
a = { az = "ap-northeast-1a" }
c = { az = "ap-northeast-1c" }
}
az = each.value.az
}
# 並びに依存しない map で返す
output "subnet_ids_by_key" {
value = { for k, m in module.subnet : k => m.id }
description = "キーごとのサブネットID(a/c などの論理名をキーにする)"
}
# 順序が必要ならソートして list で返す
output "subnet_ids_sorted" {
value = sort([for k, m in module.subnet : m.id])
description = "安定ソート済みのサブネットID一覧"
}
# オブジェクトで契約を明示
output "network_contract" {
value = {
vpc_id = module.network.vpc_id
subnet_ids = sort([for k, m in module.subnet : m.id])
region = var.region
}
description = "上位に公開するネットワーク契約(将来はキー追加で拡張)"
}sensitive=true を設定すると、CLI 出力や UI 表示で値が伏せられます。ただし Terraform の状態(state)には実値が保持されるため、バックエンドの暗号化、RBAC、最小権限が必須です。機密値は可能な限り出力しない設計が第一で、やむを得ず出力する場合も可視範囲を最小化します。
sensitive は式に伝播します。機密値を含む計算結果は自動的に sensitive になり、必要な場面のみ nonsensitive() で解除します(表示やログへの漏えいに注意)。CLI では terraform output で機密出力は既定で表示されません。自動処理が必要な場合は -json や -raw を安全な実行環境からのみ用います。
| 対象 | 表示挙動(CLI/UI) | state への保存 | 典型用途 |
|---|---|---|---|
| output(sensitive=false) | 平文表示される | 実値が保存される | 接続先URL、ID、DNS名など |
| output(sensitive=true) | 既定でマスク/非表示 | 実値が保存される(要保護) | 最小限のシークレット(避けられない場合) |
| variable(sensitive=true) | plan/apply ログでマスク | 該当値は state に入る可能性あり(リソース属性に反映されるため) | 入力時の秘匿(例: 外部シークレットを渡す) |
sensitive と nonsensitive の使い分け
# 子モジュールで機密値を返す必要があるケース
output "db_password" {
value = random_password.db.result
sensitive = true
description = "DB パスワード(表示はマスク)"
}
# 親で一部だけを再出力(原則は避ける)
output "db_connection_info" {
value = {
endpoint = module.db.endpoint
username = var.db_user
// パスワードは出さない or どうしても必要なら sensitive=true にする
}
}
# 機密を含むが公開したい一部の値のみを非機密として再計算
output "public_url" {
value = nonsensitive(module.web.public_url)
description = "公開URL(機密を含まない)"
}通常、output の依存関係は value の式から自動解決されます。まれに、副作用的な前提を満たしてから出力を評価したい場合(例: 補助モジュールの完了シグナルを待つ)、output に depends_on を追加して順序を明示できます。
depends_on はリソース作成順を直接変えるためではなく、出力の評価が特定の完了を待つことを保証する用途で使います。
出力評価を明示的に遅延させる例
# app と db の完了を待ってから true を出力
output "bootstrap_complete" {
value = true
depends_on = [module.app, module.db]
description = "主要モジュールの適用完了シグナル"
}
# 別例: シークレットの発行完了を待ってからエンドポイントを表示
output "service_endpoint_ready" {
value = module.svc.endpoint
depends_on = [aws_secretsmanager_secret_version.api_token]
}出力名の変更や型の変更は親モジュールを破壊します。モジュールの公開インターフェースと考え、命名・型・意味を安定させます。非推奨化は、旧出力をしばらく残し description に Deprecation を明記するのが無難です。
破壊的変更が不可避な場合は新しいメジャーバージョンのタグを切り、CHANGELOG とサンプルの更新、モジュール利用側のマイグレーション手順を提供します。
非推奨出力を併存させる例
# 旧: base_url は非推奨、新: service_url を使用
output "base_url" {
value = module.web.public_url
description = "[DEPRECATED] 代わりに service_url を使用してください"
}
output "service_url" {
value = module.web.public_url
description = "サービスの公開URL(正式名称)"
}Associate
問題 1
子モジュール modules/web が output "alb_dns" を定義しています。ルートモジュールでこの値を別名で再出力する正しい方法はどれですか?
正解: A
同一構成内では module.<子モジュール名>.<出力名> で参照します。terraform_remote_state は別ワークスペースの outputs を読む場合に使用します。
terraform output の実用コマンドは?
terraform output で一覧、terraform output name で個別、-json で機械可読、-raw name で改行や引用なしの単一値を取得できます。機密値は既定で表示されない点に注意してください。
機密情報を outputs に載せても良いですか?
原則は避けるべきです。やむを得ない場合は sensitive=true を設定し、バックエンドの暗号化とアクセス制御を徹底します。取得は最小権限の自動化ランナーからのみ行い、ログ出力を禁止します。
別ワークスペースの値を参照する最適解は?
安定した契約の下で terraform_remote_state データソースを用い、参照元を疎結合に保つのが一般的です。組織運用ではバックエンドの認可・暗号化・バージョン管理をセットで運用してください。
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を用いた既存リソース参照の基本、選択基準、評価順序、...