Sensitive Outputs
ทำให้ output ไม่แสดงค่าใน plan/apply log — เหมาะกับ password, API key, credentials
Sensitive Output Block
output "db_password" {
value = random_password.db.result
sensitive = true
}
หลัง apply:
Outputs:
db_password = <sensitive>
ทำไมต้อง Sensitive?
❌ ไม่ระบุ sensitive
$ terraform apply
...
Outputs:
db_password = "myS3cr3tP@ss" # ← เห็นใน log!
ปัญหา:
- Log ใน CI/CD เห็นได้
- Terminal history เห็นได้
- คนอื่นมองข้ามไหล่เห็นได้
✅ ระบุ sensitive
$ terraform apply
...
Outputs:
db_password = <sensitive>
เข้าถึงค่า Sensitive
ค่ายังอยู่ใน state — เรียกผ่าน CLI ได้:
# ดูค่า
terraform output db_password
# Raw value
terraform output -raw db_password
# JSON output (ทุก output รวมถึง sensitive)
terraform output -json
Sensitive Propagation
ถ้าใช้ค่า sensitive ในที่อื่น — Terraform จะ propagate ความ sensitive:
variable "db_password" {
type = string
sensitive = true
}
resource "random_string" "suffix" {
length = 8
}
# ค่านี้จะ sensitive อัตโนมัติ เพราะใช้ var.db_password
locals {
db_url = "postgres://admin:${var.db_password}@db.example.com/mydb"
}
output "db_url" {
value = local.db_url
sensitive = true # ต้องระบุ — ไม่งั้น Terraform error!
}
ถ้าลืมระบุ sensitive = true:
Error: Output refers to sensitive values
Functions ที่ลบ Sensitive
ถ้าต้องการ "แค่บางส่วน" ของค่า sensitive (เช่น แสดงแค่ 4 ตัวท้ายของ API key):
output "api_key_last4" {
value = "...${substr(var.api_key, -4, -1)}"
sensitive = false # ปลอดภัย เพราะแค่ 4 ตัวท้าย
}
แต่ Terraform จะ error เพราะ var.api_key sensitive
→ ใช้ nonsensitive() function:
output "api_key_last4" {
value = "...${substr(nonsensitive(var.api_key), -4, -1)}"
sensitive = false
}
ใช้ nonsensitive() ด้วยความระวัง
nonsensitive() = เอา sensitive marker ออก → log เห็นค่าได้
ใช้เฉพาะตอนที่ค่าที่ output ไม่ leak secret จริงๆ
Sensitive ≠ Encrypted
Sensitive แค่ "ซ่อนจาก log"
- ❌ ค่ายังเก็บ plain text ใน state file
- ❌ ใครเข้าถึง state file ได้ก็เห็นค่า
- ✅ Sensitive แค่ป้องกัน leak จาก output/log
ถ้าต้องการความปลอดภัยจริง:
- Encrypted backend — S3 + KMS encryption
- External secret manager — AWS Secrets Manager / Vault
- State permissions — IAM ที่จำกัดคนเข้าถึง
# ใช้ AWS Secrets Manager แทนเก็บใน state
data "aws_secretsmanager_secret_version" "db" {
secret_id = "prod/db-password"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db.secret_string
}
# อย่า output password — ให้ user ไปหาเองที่ Secrets Manager
output "db_secret_arn" {
value = data.aws_secretsmanager_secret_version.db.arn
}
Pattern: Generated Password
# Generate random password
resource "random_password" "db" {
length = 32
special = true
}
# Store in Secrets Manager
resource "aws_secretsmanager_secret" "db_password" {
name = "prod/db-password"
}
resource "aws_secretsmanager_secret_version" "db_password" {
secret_id = aws_secretsmanager_secret.db_password.id
secret_string = random_password.db.result
}
# Use in RDS
resource "aws_db_instance" "main" {
password = random_password.db.result
}
# Don't output the password — just the ARN
output "db_secret_arn" {
value = aws_secretsmanager_secret.db_password.arn
description = "Fetch password using: aws secretsmanager get-secret-value --secret-id $(terraform output -raw db_secret_arn)"
}
Sensitive Variable + Output
# Input
variable "api_key" {
type = string
sensitive = true
}
# Pass to resource (state stores it)
resource "aws_lambda_function" "api" {
function_name = "api"
environment {
variables = {
API_KEY = var.api_key
}
}
}
# Output reference, not value
output "lambda_arn" {
value = aws_lambda_function.api.arn
}
# ❌ DON'T output the secret
# output "api_key" { value = var.api_key }
ดู Sensitive ใน State (ระวัง)
# ดู state ทั้งหมด (รวม sensitive!)
terraform show
# Pull state ลง local
terraform state pull > state.json
# State file มีค่าจริง — เก็บอย่างระวัง
Best Practices
✅ DO:
- ใช้ sensitive = true กับทุก secret
- ใช้ external secret manager เก็บ secret จริงๆ
- Output แค่ ARN/reference ของ secret ไม่ใช่ค่า
- Encrypt remote backend (S3 + KMS)
❌ DON'T:
- ห้ามใช้ nonsensitive() แบบไม่จำเป็น
- ห้าม output password ใน plain text
- ห้ามคิดว่า sensitive = encrypted (ไม่ใช่)
- ห้าม commit state file
สรุป
sensitive = trueซ่อนค่าจาก output/log- Sensitive propagate อัตโนมัติเมื่อใช้ในที่อื่น
- ใช้
nonsensitive()ลบ marker (ระวัง) - Sensitive ไม่ใช่ encryption — state ยังเก็บ plain text
- Production แนะนำใช้ external secret manager (Secrets Manager / Vault)
ต่อไป → Preconditions