Sensitive Output #
Menandai output sebagai sensitive = true adalah langkah yang benar — tapi sering dipahami secara berlebihan. sensitive tidak mengenkripsi nilai, tidak menghapusnya dari state, dan tidak mencegah siapapun yang punya akses ke state untuk membacanya. Yang dilakukan sensitive hanyalah menyembunyikan nilai dari output terminal. Memahami batas ini penting agar kamu tidak salah merasa aman sementara nilai sensitif sebenarnya masih bisa diakses di berbagai tempat.
Cara Mendeklarasikan Output Sensitif #
# outputs.tf
output "database_password" {
description = "Password database — dioper ke deployment pipeline via TF_VAR_*"
value = var.db_password
sensitive = true
}
output "rds_connection_string" {
description = "Connection string lengkap untuk database production"
value = "postgresql://${var.db_username}:${var.db_password}@${aws_db_instance.main.endpoint}/${var.db_name}"
sensitive = true
}
output "api_credentials" {
description = "Credential untuk API eksternal"
sensitive = true
value = {
key = var.api_key
secret = var.api_secret
url = aws_apigatewayv2_api.main.api_endpoint
}
}
Apa yang sensitive Lindungi dan Tidak Lindungi
#
# APA YANG DILINDUNGI oleh sensitive = true:
terraform output
# Outputs:
# database_password = <sensitive> ← tersembunyi di terminal
# instance_public_ip = "54.123.45.67"
terraform apply
# ... (output sensitive tidak ditampilkan di log apply)
terraform plan
# ... (nilai sensitive tidak tampil di diff)
# APA YANG TIDAK DILINDUNGI:
# 1. Nilai masih tersimpan plaintext di state file
cat terraform.tfstate | grep -A5 '"database_password"'
# "value": "super-secret-password-123" ← MASIH BISA DIBACA
# 2. Masih bisa diakses via terraform output -raw
terraform output -raw database_password
# super-secret-password-123 ← TAMPIL jika diakses secara eksplisit
# 3. Masih bisa diakses via terraform output -json
terraform output -json
# { "database_password": { "value": "super-secret-password-123", ... } }
Sensitive Merambat ke Resource #
Ketika variable atau output ditandai sensitive, Terraform secara otomatis memperlakukan nilai yang berasal darinya sebagai sensitif juga.
variable "db_password" {
type = string
sensitive = true
}
resource "aws_db_instance" "main" {
password = var.db_password # Nilai sensitive "merambat" ke resource ini
}
# Di output plan, atribut password pada resource ini
# akan ditampilkan sebagai (sensitive value) bukan nilai aslinya:
#
# ~ resource "aws_db_instance" "main" {
# ~ password = (sensitive value)
# }
Strategi Aman untuk Nilai Sensitif #
sensitive = true hanyalah satu lapisan perlindungan, dan lapisan yang paling lemah. Strategi yang lebih kuat dimulai dari bagaimana credential dikelola sejak awal.
# STRATEGI 1: Jangan generate credential di Terraform jika bisa dihindari
# Biarkan secrets manager yang mengelola dan merotasi credential
# ANTI-PATTERN: Generate password di Terraform
resource "random_password" "db" {
length = 16
special = true
}
resource "aws_db_instance" "main" {
password = random_password.db.result
# Password tersimpan di state — siapapun akses state bisa baca password
}
# BENAR: Biarkan RDS manage password sendiri (AWS Secrets Manager rotation)
resource "aws_db_instance" "main" {
manage_master_user_password = true
# Password dikelola AWS Secrets Manager, tidak ada di state Terraform
}
# STRATEGI 2: Baca secret dari secrets manager, jangan generate
data "aws_secretsmanager_secret_version" "db" {
secret_id = "production/myapp/database"
}
locals {
db_creds = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)
}
resource "aws_db_instance" "main" {
username = local.db_creds.username
password = local.db_creds.password
# Secret tidak di-generate Terraform, tidak "dimiliki" Terraform
# Terraform hanya membaca dan menggunakannya
}
# STRATEGI 3: Output hanya apa yang perlu, bukan seluruh credential
# Daripada output password langsung, output referensi ke secrets manager
output "db_secret_arn" {
description = "ARN secret di Secrets Manager — gunakan ini untuk akses credential"
value = aws_secretsmanager_secret.db.arn
# Tidak perlu sensitive — ARN bukan credential, hanya referensi ke credential
}
# Aplikasi/pipeline yang butuh credential akan akses Secrets Manager langsung
# menggunakan ARN ini, bukan membacanya dari Terraform output
Mengaudit Output Sensitif di State #
Karena state menyimpan nilai sensitif dalam plaintext, penting untuk tahu di mana nilai sensitif tersimpan dan memastikan akses ke state dibatasi dengan tepat.
# Cek apakah ada nilai sensitive yang tersimpan di state
terraform state pull | python3 -c "
import json, sys
state = json.load(sys.stdin)
for resource in state.get('resources', []):
for instance in resource.get('instances', []):
attrs = instance.get('attributes', {})
for key, val in attrs.items():
if any(keyword in key.lower() for keyword in ['password', 'secret', 'key', 'token']):
print(f\"{resource['type']}.{resource['name']}: {key} = ***\")
"
# Batasi akses ke state dengan IAM policy (S3 backend)
resource "aws_iam_policy" "terraform_state_read" {
name = "terraform-state-read"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = [
aws_s3_bucket.terraform_state.arn,
"${aws_s3_bucket.terraform_state.arn}/*"
]
# Batasi ke principal yang memang butuh akses state
}
]
})
}
Ringkasan #
sensitive = truehanya menyembunyikan dari terminal — nilai masih tersimpan plaintext di state dan masih bisa dibaca viaterraform output -raw.- State adalah sumber kebenaran yang perlu diamankan — enkripsi at rest, akses terbatas via IAM, dan audit log akses S3 lebih penting dari
sensitiveflag.- Hindari generate credential di Terraform jika bisa — credential yang di-generate Terraform tersimpan di state. Gunakan managed rotation (seperti AWS Secrets Manager) jika tersedia.
- Baca dari secrets manager, jangan store di state — biarkan credential dikelola sistem yang memang dirancang untuk itu.
- Output referensi ke secrets manager (ARN, ID) lebih aman dari output credential langsung — konsumen mengambil credential sendiri dari sumber yang tepat.
- Sensitive “merambat” — nilai dari variable atau resource yang sensitive akan otomatis diperlakukan sensitive oleh Terraform di sepanjang rantai penggunaannya.
← Sebelumnya: Output Contract Berikutnya: Apa itu Datasource? →