0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Terraform】シークレット情報を安全に扱いたい~sensitiveとephemeralの使い分け~

0
Last updated at Posted at 2026-08-04

はじめに

本番環境で Terraform を運用する際、パスワードや API キーといった機密情報(シークレット)の扱いには細心の注意が必要です。
Terraform の変数定義(variable)には、値を保護するためのオプションとしてsensitiveephemeral(日本語で「一時的な・儚い」という意味)の2種類が存在します。しかし、一見すると「どちらも隠すための機能」に見えてしまい、使い分けや内部的な挙動の違いがわかりにくいと感じる方も多いのではないでしょうか。
そこで本記事では、この2つのオプションの組み合わせ(全4パターン)を作成し、「ファイル出力」「画面ログ(CLI)」「Outputsセクション」「Stateファイル」の4箇所でどのような差が出るのかを実際に動かして徹底検証してみました。

TL;DR

この記事を読めば、以下のことができるようになります。

  • sensitiveephemeralの役割の違いが理解できる
  • 変数の出力先(ファイル / CLI / Outputsセクション / Stateファイル)ごとに、どのようなセキュリティ保護がかかるかが把握できる
  • シークレットの性質に合わせて、どちらのオプションを指定すべきか正しく判断できるようになる

前提条件

  • なし

実行環境

  • Terraform: v1.15.5

詳細

1. 変数パターン

検証の目的と観点

今回は、Terraform の変数オプションである sensitiveephemeral の有効・無効を組み合わせた 4つの変数パターン(A〜D) を作成しました。
それらの変数を使い、以下の 4つの出力先(観点) でどのような挙動の違い(平文表示されるか、マスクされるか、エラーになるか)が出るかを検証します。

  1. ファイル出力 (local_file 等)
    • ローカルに作成したテキストファイル内に変数の値が書き込まれるか
  2. CLIへの出力 (local-exec)
    • terraform apply 実行時の画面ログ(標準出力)で値が表示されるか
  3. Outputsセクションへの出力 (output ブロック)
    • terraform apply 実行完了後に表示される Outputsセクションに出力できるか
  4. stateファイルへの出力 (terraform.tfstate)
    • インフラ状態を記録する State ファイル内に値が残るか

検証結果サマリー

検証結果の全体像は以下の通りです。

  • 1. ファイル出力(local_file 等)
    • パターンA・Bは出力可能(※パターンBはファイル内には平文で書き込まれる点に注意)
    • パターンC・D(ephemeral)はエラーとなる
  • 2. CLIへの出力(実行中の画面ログ)
    • パターンAのみ平文表示
    • パターンB(sensitive)だけでなく、パターンC・D(ephemeral)も画面露出を防ぐため自動的に秘匿される
  • 3. Outputsセクションへの出力 (output ブロック)
    • パターンA・Bは定義可能(※パターンBは sensitive = true の明記が必須)
    • パターンC・D(ephemeral)はエラーとなる
  • 4. stateファイルへの出力 (terraform.tfstate)
    • パターンA・Bは平文で残る(※sensitive を指定しても State には平文で保存される)
    • パターンC・D(ephemeral)は一切記録されない
パターン 1. ファイル出力
local_file 等)
2. CLIへの出力
(実行中の画面ログ)
3. Outputsセクションへの出力
output ブロック)
4. stateファイルへの出力
terraform.tfstate
A: 通常変数
val_normal
出力可能 平文表示 平文表示 平文表示
B: sensitive のみ
val_sensitive_only
出力可能 マスクされる マスク表示(※1) 平文表示
C: ephemeral のみ
val_ephemeral_only
エラー マスクされる エラー(定義不可) 一切記録されない
D: 両方 true
val_both_true
エラー マスクされる エラー(定義不可) 一切記録されない

※1: output ブロック側にも sensitive = true の明記が必須です。

  • 変数の定義コード
    • 検証に使用した A〜D の4パターンの変数定義です。内容は、後述の main.tf 内の変数定義と同じです。
variable "val_normal" {
  type      = string
  default   = "SECRET_PATTERN_A_NORMAL"
  sensitive = false
  ephemeral = false
}

variable "val_sensitive_only" {
  type      = string
  default   = "SECRET_PATTERN_B_SENSITIVE"
  sensitive = true
  ephemeral = false
}

variable "val_ephemeral_only" {
  type      = string
  default   = "SECRET_PATTERN_C_EPHEMERAL"
  sensitive = false
  ephemeral = true
}

variable "val_both_true" {
  type      = string
  default   = "SECRET_PATTERN_D_BOTH"
  sensitive = true
  ephemeral = true
}

2. テスト用ファイル

検証に使用したmain.tfの全体コードです。

terraform {
  required_version = ">= 1.10.0"
}

# ==========================================
# 変数の定義(4つの組み合わせパターン)
# ==========================================

variable "val_normal" {
  type      = string
  default   = "SECRET_PATTERN_A_NORMAL"
  sensitive = false
  ephemeral = false
}

variable "val_sensitive_only" {
  type      = string
  default   = "SECRET_PATTERN_B_SENSITIVE"
  sensitive = true
  ephemeral = false
}

variable "val_ephemeral_only" {
  type      = string
  default   = "SECRET_PATTERN_C_EPHEMERAL"
  sensitive = false
  ephemeral = true
}

variable "val_both_true" {
  type      = string
  default   = "SECRET_PATTERN_D_BOTH"
  sensitive = true
  ephemeral = true
}

# ==========================================
# 1. ファイル出力
# ==========================================

# A・B:一般的なファイル生成(ファイルの中身および Stateファイル内に平文で残る)
resource "local_file" "test_regular" {
  filename = "${path.module}/regular_output.txt"
  content  = <<EOT
A: ${var.val_normal}
B: ${var.val_sensitive_only}
EOT
}

# C・D:ephemeralはファイル作成リソースに渡せない

# ==========================================
# 2. CLIへの出力
# ------------------------------------------
# depends_on を使うことで、A ➔ B ➔ C ➔ D の順番で直列実行させてログを見やすくしています。
# ==========================================

# A:通常変数
resource "terraform_data" "test_A" {
  triggers_replace = [timestamp()]
  provisioner "local-exec" {
    command = "echo 'A (normal)   : ${var.val_normal}'"
  }
}

# B:Sensitive変数(Aの後に実行)
resource "terraform_data" "test_B" {
  depends_on       = [terraform_data.test_A]
  triggers_replace = [timestamp()]
  provisioner "local-exec" {
    command = "echo 'B (sensitive): ${var.val_sensitive_only}'"
  }
}

# C:Ephemeral変数(Bの後に実行)
resource "terraform_data" "test_C" {
  depends_on       = [terraform_data.test_B]
  triggers_replace = [timestamp()]
  provisioner "local-exec" {
    command = "echo 'C (ephemeral): ${var.val_ephemeral_only}'"
  }
}

# D:両方 true(Cの後に実行)
resource "terraform_data" "test_D" {
  depends_on       = [terraform_data.test_C]
  triggers_replace = [timestamp()]
  provisioner "local-exec" {
    command = "echo 'D (both)     : ${var.val_both_true}'"
  }
}

# ==========================================
# 3. Outputsセクションへの出力
# ==========================================

# A: 記述可能(CLIに平文表示、Stateに平文保存)
output "out_A_normal" {
  value = var.val_normal
}

# B: 記述可能(CLIでは <sensitive> マスク、Stateには平文保存)
# ※ sensitiveな変数を直接出力するため sensitive = true が必須
output "out_B_sensitive" {
  value     = var.val_sensitive_only
  sensitive = true
}

# C・D:ephemeralはエラーになるため定義不可

3. 実行結果

main.tfがあるフォルダで以下のコマンドを実行し、結果を確認します。

$ terraform init
$ terraform apply

3-1. ファイル出力

regular_output.txtは以下のようになりました。
パターンB(sensitive = true)の変数を渡していますが、生成されたファイルを開くと中身は平文で書き込まれています。
sensitive = trueは「暗号化機能」ではなく、あくまで「画面表示を隠す機能」であるため、ファイルなどの外部リソースに渡した場合はそのまま出力されます。

regular_output.txt
A: SECRET_PATTERN_A_NORMAL
B: SECRET_PATTERN_B_SENSITIVE

3-2. CLIへの出力

以下、terraform apply実行時のターミナルログ(一部抽出)です。パターンA以外はすべて (output suppressed due to...) と秘匿されました。
sensitiveはもちろんですが、ephemeralに設定した変数も、CLIログへの事故流出を防ぐため自動で秘匿されます。

terraform_data.test_A (local-exec): A (normal)   : SECRET_PATTERN_A_NORMAL
terraform_data.test_B (local-exec): (output suppressed due to sensitive value in config)
terraform_data.test_C (local-exec): (output suppressed due to ephemeral value in config)
terraform_data.test_D (local-exec): (output suppressed due to sensitive, ephemeral value in config)

3-3. Outputsセクションへの出力

以下、terraform apply完了時に画面へ表示されるOutputsセクションの結果です。
パターンBの変数を出力する際は、outputブロック内にもsensitive = trueを明記しないとエラーになります。
画面上では<sensitive>と秘匿されますが、裏のStateファイルには平文で記録されます。

Outputs:

out_A_normal = "SECRET_PATTERN_A_NORMAL"
out_B_sensitive = <sensitive>

3-4. stateファイルへの出力

実行後に生成されたterraform.tfstateファイルの中身(抜粋)です。
画面上では隠されていたパターンB(SECRET_PATTERN_B_SENSITIVE)の値がterraform.tfstate内には平文になっています。
一方で、パターンC・D(ephemeral)の値はStateファイル内のどこにも残っていません。

{
  "version": 4,
  "terraform_version": "1.15.5",
  "serial": 137,
  "lineage": "36c2ab77-f59e-024c-3e90-ab3ce84fba8d",
  "outputs": {
    "out_A_normal": {
      "value": "SECRET_PATTERN_A_NORMAL",
      "type": "string"
    },
    "out_B_sensitive": {
      "value": "SECRET_PATTERN_B_SENSITIVE",
      "type": "string",
      "sensitive": true
    }
  },
  "resources": [
    {
      "mode": "managed",
      "type": "local_file",
      "name": "test_regular",
      "provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "content": "A: SECRET_PATTERN_A_NORMAL\nB: SECRET_PATTERN_B_SENSITIVE\n",
            "content_base64": null,

さいごに

今回の検証を通して、sensitiveephemeralの役割の違いがはっきりと見えてきました。

  • sensitive: 画面表示するかを制御する機能
    • CLI ログなどでの映り込みを防ぐ
    • ただし、生成ファイルやterraform.tfstateには平文で保存される
  • ephemeral: Stateファイルに残すかを制御する機能
    • terraform.tfstateファイルへの保管を防ぐ
    • ただし、後でシークレット情報を参照できなくなるので注意
    • 一時的なパスワードやトークンなどの重要なシークレットに最適

目的を明確にして、正しく使い分けていきましょう!

参考URL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?