1. 概要
この記事では、以下の内容を解説します。
outputブロックの基本構文と全引数(value/description/sensitive/depends_on/precondition)- ルートモジュールでの
outputの使い方(terraform outputコマンド) - モジュールの
outputを親モジュールで参照する方法 sensitive出力のマスク仕様- よくある間違いと対処法
outputブロックは、Terraformが作成したリソースの情報(IPアドレス・ARN・ID等)を外部に公開するための仕組みです。モジュール間の値の橋渡しとして特に重要です。
2. outputブロックとは
outputブロックで定義した値は以下の2つの用途に使われます。
用途1: terraform applyの完了後に値を表示する(ルートモジュール)
→ EC2のIPアドレス、RDSのエンドポイント等をコンソールに出力
用途2: モジュールの値を親モジュールで参照できるようにする
→ module.<NAME>.<OUTPUT_NAME> の形式で参照
output "instance_public_ip" {
description = "EC2インスタンスのパブリックIPアドレス"
value = aws_instance.web.public_ip
}
3. 基本構文と全引数
output "<出力名>" {
value = <式> # 必須: 出力する値
description = "<説明>" # 任意: 説明文
sensitive = <true/false> # 任意: マスク表示
depends_on = [<リソース>] # 任意: 明示的な依存
}
全引数一覧
| 引数 | 必須 | 説明 |
|---|---|---|
value | ✅ | 出力する値。任意のTerraform式が使える |
description | 任意 | 出力の説明文。ドキュメント生成に使われる |
sensitive | 任意 | trueにするとterraform output時にマスク表示 |
depends_on | 任意 | 暗黙的な依存関係が作れない場合に明示する |
4. ルートモジュールでのoutput
terraform outputコマンドで確認する
terraform apply実行後、定義したoutputの値が自動表示されます。後から確認するにはterraform outputコマンドを使います。
# main.tf
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
tags = {
Name = "web"
Environment = "dev"
ManagedBy = "terraform"
}
}
# outputの定義
output "instance_id" {
description = "EC2インスタンスのID"
value = aws_instance.web.id
}
output "instance_private_ip" {
description = "EC2インスタンスのプライベートIPアドレス"
value = aws_instance.web.private_ip
}
# apply後に出力を確認
terraform output
# 特定の出力だけ確認
terraform output instance_private_ip
# JSON形式で出力(スクリプトとの連携に便利)
terraform output -json
sensitive — 出力のマスク
sensitive = trueを設定すると、terraform outputの標準実行では値がマスクされます。
output "db_password" {
description = "RDSのマスターパスワード(機密値)"
value = random_password.db.result
sensitive = true # コンソール出力でマスクされる
}
# sensitive = trueの出力
terraform output db_password
# → (sensitive value) ← マスク表示
# 実際の値を確認するには -json または -raw
terraform output -raw db_password
# → your-actual-password
⚠️ 注意:
sensitive = trueにしても、terraform.tfstateファイルには平文で記録されます。Stateファイルのアクセス権限管理が必要です。
depends_on — 出力前の明示的な依存
outputブロックにもdepends_onを設定できます。リソース間に暗黙的な依存関係が作れない場合に使います。
output "endpoint" {
description = "アプリケーションのエンドポイント"
value = aws_lb.main.dns_name
# IAMポリシーのアタッチが完了してからoutputを確定させる
depends_on = [
aws_iam_role_policy_attachment.app
]
}
5. モジュールでのoutput
サブモジュールの値を親モジュールで参照する
モジュール内でoutputを定義すると、呼び出し元からmodule.<NAME>.<OUTPUT_NAME>の形式で参照できます。
# modules/vpc/outputs.tf(サブモジュール内)
output "vpc_id" {
description = "作成したVPCのID"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "プライベートサブネットIDのリスト"
value = aws_subnet.private[*].id
}
output "public_subnet_ids" {
description = "パブリックサブネットIDのリスト"
value = aws_subnet.public[*].id
}
# main.tf(ルートモジュール)
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
environment = var.environment
}
# モジュールのoutputを参照: module.<モジュール名>.<output名>
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
subnet_id = module.vpc.private_subnet_ids[0] # ← モジュールのoutputを参照
tags = {
Name = "web"
Environment = var.environment
ManagedBy = "terraform"
}
}
# ルートのoutputでモジュールの値を再公開
output "vpc_id" {
description = "VPCのID"
value = module.vpc.vpc_id # モジュールの値をそのまま公開
}
map型のoutputでまとめて出力する
関連する値をまとめてmapで返すパターンは可読性が高くなります。
# モジュールのoutputs.tf
output "endpoints" {
description = "各サービスのエンドポイント情報"
value = {
alb_dns = aws_lb.main.dns_name
rds_host = aws_db_instance.main.address
redis_host = aws_elasticache_cluster.main.cache_nodes[0].address
}
}
# 呼び出し元での参照
resource "aws_ssm_parameter" "app_config" {
name = "/app/config/alb_endpoint"
type = "String"
value = module.app.endpoints.alb_dns # mapの属性にアクセス
}
6. よくある間違い
outputの名前でリソースを参照しようとした
# ❌ outputブロックでresourceを参照するとき属性名を間違えやすい
output "instance_ip" {
value = aws_instance.web.public_ip # public_ipはattr名
}
# → aws_instance.webがElastic IPなしの場合、空文字列が返る
# → Elastic IPを使う場合は aws_eip.main.public_ip を参照すべき
循環参照エラー
│ Error: Cycle: aws_instance.web, output.instance_ip
原因: outputがリソースを参照し、そのリソースが別の方法でoutputに依存している循環が発生している。
解決方法: depends_onを使わずに参照式だけで依存関係を表現するように整理する。
モジュールのoutputを参照するのにsensitiveが伝播する
モジュール内でsensitive = trueのoutputを定義すると、それを参照するルートモジュールの値も自動的にsensitive扱いになります。
# モジュール内
output "db_connection_string" {
value = "mysql://admin:${var.db_password}@${aws_db_instance.main.address}/app"
sensitive = true
}
# ルートモジュール
output "app_db_url" {
# module.db.db_connection_stringがsensitiveなため、この値も自動的にsensitiveになる
value = module.db.db_connection_string
# sensitive = true を書かなくても自動でマスクされる
}
7. 関連記事
- variable(入力変数)の使い方 — outputに対する「入力側」
- moduleブロックの使い方 — モジュール間のoutputの受け渡し
- state管理とは — sensitiveなoutputとStateファイルの関係
- terraform init / plan / apply / destroyの使い方 —
terraform outputコマンド - locals(ローカル値)— DRYなコードを書く
- sensitive変数 — 機密値のマスクとstate記録
8. まとめ
outputブロックで定義した値はterraform apply後にコンソールに表示され、terraform outputコマンドで確認できる- モジュール内のoutputは
module.<NAME>.<OUTPUT_NAME>で親から参照できる - 必須引数は
valueのみ。残りは任意(description/sensitive/depends_on) sensitive = trueでコンソール出力をマスクできるが、Stateファイルには平文記録される- map型のoutputで複数の値をまとめて返すとモジュール設計がすっきりする
depends_onはoutputにも設定できるが、必要なケースは少ない
動作確認バージョン: Terraform >= 1.9 / AWS Provider ~> 5.0 対象リージョン: ap-northeast-1(東京) 公式ドキュメント: https://developer.hashicorp.com/terraform/language/values/outputs