メインコンテンツにスキップ
aws

Terraform の 「Output refers to sensitive values」 エラーを解決する

タグ: 🏷 terraform

Terraform を使ってIAMユーザを作成し、そのパスワードを表示したいです。その場合 Error: Output refers to sensitive values というエラーに遭遇することがあります。これは、パスワードやAPIキーといった機微な情報を意図せず出力してしまうのを防ぐための、Terraformの安全機能によるものです。

1. エラーの概要

以下のようなコードで terraform applyterraform plan を実行した際に、このエラーが発生します。

output "password" {
  value = aws_iam_user_login_profile.tests3put.password
}

ターミナルには、次のようなメッセージが表示されます。

│ Error: Output refers to sensitive values
│   on iam.tf line 84:
│   84: output "password" {
│ To reduce the risk of accidentally exporting sensitive data that was intended to be only internal, Terraform requires that any root module output
│ containing sensitive data be explicitly marked as sensitive, to confirm your intent.
│ If you do intend to export this data, annotate the output value as sensitive by adding the following argument:
│     sensitive = true

1.1. エラーメッセージの意味

Terraform 1.0以降、「センシティブ(機微)な値」を不用意に外部へ露出させないことが、デフォルトの安全策となりました。

Error: Output refers to sensitive values というメッセージは、output "password" が内部的に「センシティブ扱い」の値を参照しているにもかかわらず、その出力設定が安全でないことを検出し、「このままでは情報漏えいのリスクがあるので処理を停止した」という警告です。

1.2. 原因

エラーの主な原因はシンプルです。

  1. パスワードやシークレットキーなど、Terraformが自動的に sensitive = true とマークした属性(例: random_password.resultaws_db_instance.master_password など)を、そのまま output で出力しようとしている。
  2. しかし、output ブロック側で sensitive = true フラグを明示的に指定していないため、Terraformが「本当にこの値を出力して良いのか?」とユーザーに確認を求めるためにエラーを発生させている。

1.3. 解決策

解決策はいくつか考えられます。状況に応じて最適なものを選択してください。

1.3.1. sensitive = true を付けて出力する

機微な値をTerraformの管理下で他のリソースに渡すなど、どうしても出力が必要な場合は、output ブロックに sensitive = true を追加します。

output "password" {
  value     = aws_db_instance.example.master_password
  sensitive = true # 明示的にセンシティブであることを宣言
}

この設定により、terraform output コマンドを実行しても、値は <sensitive> と表示され、直接ターミナルに表示されなくなります。

$ terraform output
cfront_domain_name_img = "aaaaa.cloudfront.net"
cfront_domain_name_pdf = "bbbbb.cloudfront.net"
password = <sensitive>

値を取得する必要がある場合は、-json オプションを使います。

$ terraform output -json
{
  "cfront_domain_name_img": {
    "sensitive": false,
    "type": "string",
    "value": "aaaaa.cloudfront.net"
  },
  "cfront_domain_name_pdf": {
    "sensitive": false,
    "type": "string",
    "value": "bbbbb.cloudfront.net"
  },
  "password": {
    "sensitive": true,
    "type": "string",
    "value": "password-dayo--"
  }
}

警告: この方法でも、CI/CDのログや他のファイルに値が記録されると漏えいリスクが残ります。取り扱いには十分注意してください。

1.3.2. そもそも出力しない、またはマスキングする

パスワードのような値をルートモジュールの output から出力する必要がまったくない場合は、単純にその output ブロックを削除するのが最も安全です。

あるいは、値そのものではなく、値が設定されたことだけを示すような形にマスキングする方法もあります。

output "password_set" {
  value = true # 例: パスワードが設定済みかどうかだけを示す
}

1.3.3. 一時的に開発用途で確認したい

開発中にどうしても平文で値を確認したい場合に限り、nonsensitive() 関数で値をラップする方法があります。これによりエラーは回避できますが、安全性が損なわれるため利用は慎重に行うべきです。

output "password_plaintext" {
  value = nonsensitive(aws_db_instance.example.master_password)
}

⚠️ この方法は推奨されません。 特に本番環境では絶対に避けてください。


2. まとめ

  • 原因: 機微な値を output しようとしているが、output ブロックで sensitive = true が宣言されていないため。
  • 対処:
    • 推奨: sensitive = true を付けて意図を明示するか、不要な出力自体をやめる。
    • 非推奨: nonsensitive() を使って一時的に確認する。