「Output refers to sensitive values」エラーの解決方法

1. 概要

  • 「Output refers to sensitive values」エラー
  • sensitive = trueの出力への影響
  • sensitive値がstateに残る問題
  • nonsensitive()による意図的な公開

sensitive値を含むリソース属性をoutputに出力しようとすると、Terraformはエラーまたは警告を出します。sensitive値の扱いには注意が必要です。


2. エラーメッセージ

Error: Output refers to sensitive values

  on outputs.tf line X:
   X: output "db_password" {
   X:   value = aws_db_instance.main.password

To reduce the risk of accidentally exposing values the caller does not expect,
Terraform requires that any root module output containing sensitive values be
explicitly marked as sensitive.

3. エラーの再現例

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

variable "db_password" {
  description = "DBパスワード"
  type        = string
  sensitive   = true  # sensitiveな変数
}

resource "aws_db_instance" "main" {
  identifier        = "${var.environment}-main"
  engine            = "postgres"
  engine_version    = "16"
  instance_class    = "db.t3.micro"
  allocated_storage = 20
  storage_encrypted = true
  db_name           = "myapp"
  username          = "admin"
  password          = var.db_password  # sensitiveな値を使用

  skip_final_snapshot = true

  tags = {
    Name        = "${var.environment}-main"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

# ❌ エラー: sensitiveな値を含むoutputにsensitive = trueがない
output "db_password" {
  value = var.db_password  # sensitive値をそのまま出力
}

4. 解決方法1: output に sensitive = true を追加(推奨)

# ✅ sensitive = true を明示する
output "db_password" {
  description = "DBパスワード(sensitive)"
  value       = var.db_password
  sensitive   = true  # 追加
}

# planやapplyの出力では (sensitive value) と表示される

5. 解決方法2: パスワードをoutputしない設計に変更(最推奨)

# ✅ パスワードはSecrets Managerで管理し、ARNだけをoutputする
resource "aws_secretsmanager_secret" "db_password" {
  name                    = "/${var.environment}/db/password"
  recovery_window_in_days = 0

  tags = {
    Name        = "${var.environment}-db-password"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

resource "aws_secretsmanager_secret_version" "db_password" {
  secret_id     = aws_secretsmanager_secret.db_password.id
  secret_string = var.db_password
}

# ARNだけをoutput(sensitive値そのものは出力しない)
output "db_password_secret_arn" {
  description = "DBパスワードのSecrets Manager ARN"
  value       = aws_secretsmanager_secret.db_password.arn
}

6. nonsensitive() で意図的に公開する

# 意図的にsensitiveフラグを外して公開する(慎重に使う)
output "db_endpoint" {
  description = "DBエンドポイント(公開OK)"
  value       = nonsensitive(aws_db_instance.main.endpoint)
}

# ⚠️ nonsensitive()はsensitiveフラグを外すだけで、値自体を保護するわけではない
# → 本当に公開してよい値にのみ使う

7. sensitive値がstateに残る問題

# ⚠️ sensitive = true でもstateファイルには平文で記録される
# aws_db_instance の password は state に保存される

# ✅ stateに残さない場合は ephemeral 変数(Terraform 1.10+)か
# Secrets Managerでパスワードを管理してwrite_only属性に渡す方法を使う
# stateに含まれるsensitive値を確認
terraform state show aws_db_instance.main | grep password
# password = "ACTUAL_PASSWORD_HERE"  ← stateに平文で記録されている

8. 関連記事


9. まとめ

  • sensitive値をoutputに含める場合はsensitive = trueを必ず追加する
  • 最良の設計はパスワードをoutputしない(Secrets Managerに保存してARNをoutput)
  • nonsensitive()でsensitiveフラグを外すことはできるが、値が公開されるため慎重に使う
  • sensitive = trueでもstateファイルには平文で記録される(stateファイルのアクセス制御が重要)

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output