Terraformのoutputは、構築したリソースの重要な識別子やエンドポイントを外部へ渡す“インターフェース”です。設計を誤ると、値が取れない・漏えいする・パイプラインが壊れるといった事故につながります。
本記事は、outputの定義からCLIでの安全な取得、モジュール間や別スタックへの共有、CI/CDへの受け渡しまでを、Associate試験で問われやすい観点で整理します。
outputはルートモジュール(または子モジュール)が外部へ公開する値です。適用(apply)後に状態ファイル(state)へ保存され、CLIや他のコードから参照できます。plan段階では値が未確定(known after apply)になり得る点に注意します。
sensitive = true を付けると、CLIの標準表示では値がマスクされます。ただしstateに値自体は保存されるため、stateの保護(バックエンドのアクセス制御、暗号化)が前提です。
最小の outputs.tf(機密値を含む例)
output "bucket_name" {
description = "アプリの成果物を格納するS3バケット名"
value = aws_s3_bucket.app_bucket.id
}
output "db_password" {
description = "DBユーザーの初期パスワード(表示はマスク)"
value = random_password.db.result
sensitive = true
}terraform output は適用後の出力値を一覧または個別に取得します。人間が読む場合はそのまま、機械可読にしたい場合は -json、純粋な文字列として取り出したい場合は -raw を使い分けます。
sensitive な出力は通常表示でマスクされます。-json は値を含むJSON(sensitiveフラグ付き)を返すため、自動化では扱いやすい一方で、ログ流出に注意が必要です。-raw は文字列専用で、敏感な出力には使えない(マスクやエラーになる)ことがあります。
| 取得方法 | 出力形式 | 機密値の扱い | 主な用途 |
|---|---|---|---|
| terraform output | 人間可読テキスト | 値はマスク | 手動確認 |
| terraform output name | 人間可読テキスト | 値はマスク | 個別確認 |
| terraform output -raw name | プレーン文字列 | 非機密向け(機密は不可/マスク) | 環境変数への代入など |
| terraform output -json | JSON | 値を含む(sensitive: true 付与) | CI/CD・スクリプト連携 |
| terraform show -json | JSON(state/plan全体) | stateに含まれる値は取得可 | 出力以外の情報も含めた機械処理 |
| data.terraform_remote_state | HCL経由で参照 | 参照先stateの権限に依存 | 別スタックの出力をコードから利用 |
Outputの流れ(定義→状態→取得・共有)
代表的な取得コマンド集
# 一覧(機密はマスク)
terraform output
# 個別取得(機密はマスク)
terraform output bucket_name
# 機械可読(機密値も含まれる。ログ取り扱い注意)
terraform output -json | jq '.bucket_name.value'
# 文字列だけをそのまま(非機密の文字列向け)
terraform output -raw bucket_name
# state全体をJSONでパース(outputs以外も加工したいとき)
terraform show -json | jq '.values.outputs'
子モジュールのoutputは、親モジュールから module.<name>.<output_name> で参照できます。親で再公開(ラップ)して外部インターフェースを安定化させると、内部の実装変更に強くなります。
まとめて返したい場合はオブジェクトやマップをvalueに使うと、取扱いがシンプルになります(出力に明示的な型宣言はありませんが、値としてオブジェクトを渡せます)。
子モジュールの出力を親で再公開する例
# child/outputs.tf
output "vpc" {
description = "VPCの主要属性"
value = {
id = aws_vpc.main.id
cidr = aws_vpc.main.cidr_block
rt_ids = [for r in aws_route_table.this : r.id]
}
}
# root/main.tf
module "network" {
source = "./child"
# ...
}
# root/outputs.tf
output "vpc_id" {
value = module.network.vpc.id
description = "アプリが利用するVPC ID"
}
別のステートにあるoutputを参照したい場合、data "terraform_remote_state" を使えます。たとえばネットワーク層のVPC IDをアプリ層が読み取る、という分離構成に適します。
ただしスタック間の暗黙的な依存が生まれるため、適用順序の管理(CIでネットワーク→アプリの順に実行)や、参照先ステートへのアクセス権限設定が必須です。強い結合が問題になる場合は、単一リポジトリのルート/子モジュール構成も検討してください。
terraform_remote_state で別ステートの出力を参照
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "tfstate-shared-bucket"
key = "envs/prod/network/terraform.tfstate"
region = "ap-northeast-1"
}
}
# 参照例(VPC IDを使う)
resource "aws_subnet" "app" {
vpc_id = data.terraform_remote_state.network.outputs.vpc_id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
}
自動化では terraform output -json を使い、必要なキーだけを抽出してアーティファクトや環境変数に渡します。ログへの機密値混入を避けるため、マスキング機能や権限の分離を行います。
outputをリソースの入力に直接戻すことはできないため(outputは外部公開用)、ファイル生成はCLIで行うのがシンプルです。-raw が使えない場合は -json と jq で代替します。
CIのステップ例(JSON→.env/ファイル出力)
# 1) JSONへ保存
terraform output -json > outputs.json
# 2) 必要な値だけ抽出して .env へ(機密はマスク/スキップ推奨)
VPC_ID=$(jq -r '.vpc_id.value' outputs.json)
echo "VPC_ID=$VPC_ID" >> app.env
# 3) 別形式への変換(例:システム設定用)
jq '{service_url: .service_endpoint.value, bucket: .bucket_name.value}' outputs.json > runtime_config.json
outputはapply後に取得するのが基本。planでは unknown になり得ます。sensitive=true はCLI出力のマスクであり、stateの暗号化ではありません。-json は機密値も含むため、ログ出力に注意が必要です。
別スタック参照は data.terraform_remote_state が使えますが、推奨はモジュール化による明示的な依存管理です。-raw は文字列専用で、複合型には使えません。
known after apply のイメージ
# planの表示例(概念的)
# + output "bucket_name" {
# value = (known after apply)
# }
# -> apply後に terraform output で確定値を取得
Associate
問題 1
ルートモジュールに sensitive = true のoutputがあり、その実際の値を自動化で取得して後続ジョブへ渡したい。最も適切な方法はどれか?
正解: A
sensitiveな出力は通常表示でマスクされるため、terraform output では実値が得られません。-json は値を含むJSONを返し、sensitive: trueのフラグも付与されるため自動化に適します。-rawは文字列専用かつ敏感値では使えない場合があり、テキスト出力の目視は自動化では不適切です。
sensitive = true にしていればstate内でも暗号化されますか?
いいえ。sensitiveはCLI表示や計画/適用のログで値をマスクするための属性です。stateには実値が保存されるため、バックエンドのアクセス制御・暗号化(例: S3サーバーサイド暗号化、KMS、Terraform Cloudのワークスペース設定)で保護してください。
terraform output の値が空/取得できないのはなぜ?
主な原因は以下です。1) apply前で値が未確定、2) ルートモジュールにoutputが定義されていない(子モジュールの出力を再公開していない)、3) 参照中のワークスペースやバックエンドが異なる、4) stateが壊れている/権限が足りない。まずは terraform apply の実行、workspaceやbackend設定の確認、stateの整合性確認を行ってください。
複数の値をまとめて1つのoutputにしたいのですが?
オブジェクトやマップとして value にまとめるのが実務的です。例: value = { id = aws_vpc.main.id, cidr = aws_vpc.main.cidr_block } のように返すと、利用側は module.x.vpc.id のようにドット記法で参照できます。
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を用いた既存リソース参照の基本、選択基準、評価順序、...