Output Syntax
Output = ค่าที่ Terraform "คืน" หลัง apply — ใช้ดูค่า, ส่งให้ module อื่น, หรือ pipe ใส่ shell script
Output Block
output "<NAME>" {
value = <EXPRESSION>
description = "..."
sensitive = false
depends_on = [...]
}
ตัวอย่างพื้นฐาน
outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
description = "ID of the main VPC"
}
output "public_subnet_ids" {
value = aws_subnet.public[*].id
description = "IDs of public subnets"
}
output "instance_public_ip" {
value = aws_instance.web.public_ip
description = "Public IP of web instance"
}
หลัง apply:
$ terraform apply
...
Outputs:
vpc_id = "vpc-0a1b2c3d4e5f6g7h8"
public_subnet_ids = ["subnet-aaa", "subnet-bbb"]
instance_public_ip = "54.123.45.67"
ดู Outputs
# ดูทั้งหมด
terraform output
# ดูตัวเดียว
terraform output vpc_id
# ดูแบบ raw (ไม่มี quotes — เหมาะกับ shell)
terraform output -raw instance_public_ip
# ดูแบบ JSON
terraform output -json
Use Cases
1. ส่งให้ Shell Script
#!/bin/bash
IP=$(terraform output -raw instance_public_ip)
ssh ec2-user@$IP
2. ส่งให้ Module Caller
modules/network/outputs.tf
output "vpc_id" {
value = aws_vpc.this.id
}
output "subnet_ids" {
value = aws_subnet.this[*].id
}
main.tf (caller)
module "network" {
source = "./modules/network"
# ...
}
resource "aws_instance" "web" {
subnet_id = module.network.subnet_ids[0] # ← reference module output
}
3. ส่งระหว่าง State (Remote State)
อ่านจาก state ของ project อื่น:
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "my-tfstate"
key = "network/terraform.tfstate"
region = "ap-southeast-1"
}
}
resource "aws_instance" "app" {
subnet_id = data.terraform_remote_state.network.outputs.subnet_ids[0]
}
4. CI/CD Pipeline
GitHub Actions
- name: Deploy infrastructure
run: terraform apply -auto-approve
- name: Get outputs
id: tf
run: |
echo "url=$(terraform output -raw alb_dns)" >> $GITHUB_OUTPUT
echo "bucket=$(terraform output -raw bucket_name)" >> $GITHUB_OUTPUT
- name: Deploy app
run: aws s3 sync ./dist/ s3://${{ steps.tf.outputs.bucket }}
Output Types
Output รองรับทุก type ของ HCL:
# String
output "region" {
value = var.region
}
# Number
output "port" {
value = 8080
}
# List
output "subnet_ids" {
value = aws_subnet.public[*].id
}
# Map
output "tags" {
value = local.common_tags
}
# Object
output "database" {
value = {
host = aws_db_instance.main.address
port = aws_db_instance.main.port
name = aws_db_instance.main.db_name
}
}
# Computed/conditional
output "endpoint" {
value = var.use_https ? "https://${aws_alb.main.dns_name}" : "http://${aws_alb.main.dns_name}"
}
Description (อย่าลืม!)
output "vpc_id" {
value = aws_vpc.main.id
description = "ID of the VPC. Used by other modules to deploy resources."
}
description ปรากฏใน:
terraform output(เมื่อใช้-showflag)- Module documentation
- IDE intellisense
Output ที่ Computed
ค่า output อาจ "(known after apply)" ถ้า resource ยังไม่ได้สร้าง:
$ terraform plan
...
Changes to Outputs:
+ vpc_id = (known after apply)
Output Dependencies
ถ้า output ขึ้นกับ resource ที่ Terraform อาจไม่ detect → ใช้ depends_on
output "ready" {
value = "Infrastructure is ready"
depends_on = [
aws_instance.web,
aws_route53_record.dns,
aws_acm_certificate_validation.cert,
]
}
ใช้ตอน:
- ต้องการ output ปรากฏหลัง resource สำคัญทุกตัวเสร็จ
- ทำ "completion signal" สำหรับ external tool
Sensitive Outputs
output "db_password" {
value = random_password.db.result
sensitive = true
}
Output:
db_password = (sensitive value)
ดูค่าจริง:
terraform output db_password
# → ค่าจริง
terraform output -json
# → ค่าจริงใน JSON
ดูเพิ่มใน Sensitive Outputs
ตัวอย่าง Real-World Outputs
outputs.tf
# Network
output "vpc_id" {
value = aws_vpc.main.id
description = "VPC ID"
}
output "vpc_cidr_block" {
value = aws_vpc.main.cidr_block
description = "VPC CIDR block"
}
output "public_subnet_ids" {
value = aws_subnet.public[*].id
description = "List of public subnet IDs"
}
output "private_subnet_ids" {
value = aws_subnet.private[*].id
description = "List of private subnet IDs"
}
# Compute
output "alb_dns_name" {
value = aws_alb.main.dns_name
description = "ALB DNS name"
}
output "alb_zone_id" {
value = aws_alb.main.zone_id
description = "ALB Route53 zone ID (for alias records)"
}
# Database
output "rds_endpoint" {
value = aws_db_instance.main.endpoint
description = "RDS endpoint for application connection"
}
output "rds_address" {
value = aws_db_instance.main.address
description = "RDS hostname"
}
# Secrets (sensitive)
output "rds_password" {
value = random_password.rds.result
description = "RDS master password"
sensitive = true
}
# Computed
output "application_url" {
value = "https://${aws_route53_record.app.fqdn}"
description = "Public application URL"
}
# Map (grouped output)
output "infrastructure_summary" {
value = {
vpc_id = aws_vpc.main.id
alb_dns = aws_alb.main.dns_name
rds_endpoint = aws_db_instance.main.endpoint
bucket_name = aws_s3_bucket.data.id
}
description = "Summary of infrastructure components"
}
Best Practices
✅ DO:
- ใส่ description ทุก output
- Group related outputs (network, compute, database)
- Output เฉพาะค่าที่ "ภายนอก" ต้องใช้
- ใช้ sensitive = true กับ password/secrets
❌ DON'T:
- Output ทุก attribute (มากไป = ดูยาก)
- Hard-code prefix ใน value (ใช้ template/format)
- Output secret โดยไม่ใส่ sensitive
สรุป
outputblock = ค่าที่ Terraform "คืน" หลัง apply- ดูด้วย
terraform output [name](+-raw,-json) - ใช้ส่งให้ module / shell script / CI/CD pipeline
- รองรับทุก type ของ HCL
sensitive = trueซ่อนค่าจาก outputdepends_onบังคับ ordering
ต่อไป → Sensitive Outputs