Terraform

Terraformのsensitive変数: 出力マスクの仕組みと実務の注意点【Associate対策】

2026-04-19
NicheeLab編集部

Terraformのsensitiveは「見え方を制御するためのメタ情報」であり、暗号化ではありません。CLI上の出力はマスクされますが、stateには値が格納される点が最重要です。

Associate試験では、マスク挙動・stateの扱い・出力と関数の使い分けが頻出。実務ではterraform output -jsonやログ、CIでの取り扱いが落とし穴になりがちです。

出力マスクの基本: 「見えない」だけで「消えない」

variableやoutputにsensitive = trueを付けると、terraform plan/applyやterraform outputの人間向け表示で値がマスクされます。これは露出を減らすための出力制御であり、値自体を暗号化・削除する機能ではありません。

重要なポイントは、値がTerraformのstateに保存されることです。ローカルstateは平文のJSONに近い形で保持され、remote backendでもアプリケーション層での暗号化は行いません(バックエンド側の暗号化・アクセス制御に依存)。

  • sensitiveは「表示抑制」。暗号化・秘匿化ではない。
  • CLIの対話入力でsensitive変数はエコーされない。
  • plan/applyの差分では具体値が出ず、masked表示になる。
  • stateには値が保持されるため、保存場所と権限設計が必須。

sensitive値の流れとマスク箇所

tfvars / ENV(TF_)variable(sensitive)resource argumentterraform plan/apply(人間向けはマスク)terraform console(デフォルトはマスク)Terraform state(値は保存される)terraform output (human)マスク表示sensitive値の流れとマスク箇所
# terraform output (人間向け)  -> マスク表示
# terraform output -json        -> 値は含まれるが "sensitive": true フラグ

基本の定義: 変数と出力でのsensitive指定

variable "db_password" {
  type      = string
  sensitive = true
}

# 出力も明示的にsensitiveにする
output "db_password_masked" {
  value     = var.db_password
  sensitive = true
}

# 対話入力時は値がエコーされず、plan/applyではマスクされる

変数・出力・関数・プロバイダ属性の違いを正しく使い分ける

Terraformでは、variable/outputのsensitive属性、関数sensitive()/nonsensitive()、さらにプロバイダ側スキーマのSensitive属性が絡み合います。目的に応じて正しく組み合わせることが重要です。

特に、式の中で生成された値(localsやテンプレート結果など)を機微扱いしたい場合は、関数sensitive()で明示的にタグ付けします。出力での露出を意図する場合のみnonsensitive()で剥がします。

  • variableのsensitive: 入力値の取り扱い(プロンプト/出力マスク)。
  • outputのsensitive: 出力の取り扱い。意図せぬ露出をブロック。
  • sensitive()/nonsensitive(): 計算結果の機微タグを付与/剥離。
  • プロバイダのSensitive属性: リソース/データソースのスキーマ側での機微扱い。
機能主な目的CLIの見え方/出力stateへの保存
variable sensitive入力のマスクplan/applyで値を隠す。プロンプト非エコー値は保存される
output sensitive出力のマスクterraform outputでマスク表示値は保存される
sensitive()/nonsensitive()式の機微付与/剥離人間向け表示に影響(マスク/露出)値は保存される
プロバイダ側Sensitive属性スキーマでの秘匿planの差分やログに出ないよう抑止値は保存される

関数の使い分け例

locals {
  raw        = "user"
  secret     = sensitive("p@ssw0rd")
  combined   = "${local.raw}:${local.secret}"   # combinedはsensitiveに伝播
  published  = nonsensitive(local.secret)        # 意図的に露出(推奨は最小限)
}

output "combined_masked" {
  value     = local.combined
  sensitive = true
}

# 露出が必要な場合のみ、nonsensitive()を使う
output "published_plain" {
  value     = local.published
  sensitive = false
}

CLI挙動の違い: plan/apply, output, output -json, console

人間向けのterraform plan/applyやterraform outputは、sensitive値をマスクします。terraform consoleではデフォルトで(sensitive value)と表示され、nonsensitive()で明示的に露出させるまで値は見えません。

terraform output -jsonは自動化向けで、値そのものをJSONに含めつつ、"sensitive": trueのフラグを付けます。ツール連携時は取り扱いに十分注意してください。

  • plan/apply: 機微は具体値が出ず、差分はマスクされる。
  • output: 人間向けはマスク。-jsonは値を含む可能性があるため保護必須。
  • console: デフォルトは(sensitive value)。nonsensitive()でのみ閲覧可能。
  • TF_LOGなどの詳細ログは秘匿値が漏れるリスクがあるため、常用しない。

CLIでの確認例(コメントは挙動の目安)

# terraform console
> var.db_password
(sensitive value)
> nonsensitive(var.db_password)
"p@ssw0rd"

# terraform output
$ terraform output db_password_masked
sensitive

# terraform output -json(自動化向け。取り扱い注意)
$ terraform output -json | jq '.db_password_masked'
{
  "sensitive": true,
  "type": "string",
  "value": "p@ssw0rd"  # 値が含まれる想定。保護が必要
}

stateとバックエンド: 暗号化はTerraformではなく保存先の責務

Terraformはstateにリソース属性の最終値を保持します。sensitiveであってもstateからは消えません。ローカルstateはファイル権限で守り、チーム利用では暗号化とアクセス制御が整ったremote backendを使います。

S3やGCS、Azure Storageなどのバックエンドは、サーバサイド暗号化やKMS連携が利用可能です。加えて、厳密なIAMと監査ログ、バージョニング・リーガルホールド等で漏えい時の影響を抑えます。

  • ローカルstateは.gitignore対象、600権限で管理。
  • S3 backendではSSE-KMSを推奨。バケットポリシーで限定。
  • stateは機微値を含むため、ダウンロード・バックアップの運用にも権限管理と監査を付与。
  • 履歴に残った機微情報の完全消去は難しい。ローテーションと鍵管理を前提に設計。

S3バックエンド例(暗号化とアクセス制御の前提化)

terraform {
  backend "s3" {
    bucket         = "my-tf-state-bucket"
    key            = "env/prod/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true            # SSE有効化
    kms_key_id     = "arn:aws:kms:ap-northeast-1:123456789012:key/xxxx"
    dynamodb_table = "tf-state-lock" # ロック推奨
  }
}

# 参考: stateの一部は次のように値を保持(概念イメージ)
# {
#   "resources": [
#     {
#       "type": "example_resource",
#       "instances": [
#         { "attributes": { "password": "p@ssw0rd" } }
#       ]
#     }
#   ]
# }

CI/CDとログでのベストプラクティス

CIでは、変数は環境変数TF_VAR_やCIのSecrets機能から渡し、tfvarsファイルをリポジトリに含めない運用が基本です。terraform output -jsonの扱いには特に注意し、ログやアーティファクトで露出しないようマスキング・アクセス制御を行います。

高詳細ログ(TF_LOG=DEBUG/TRACE)は不用意に機微値を含み得ます。必要時のみ一時的に使い、出力先は限定・破棄を徹底します。

  • CIのSecretsストアを使用し、TF_VAR_xxxで受け渡し。
  • ログとアーティファクトに出力する場合はマスク規則を設定。
  • outputは最小限・短命に。長期保管は避ける。
  • VaultやクラウドのSecret Managerと連携し、動的クレデンシャルを優先。

GitHub Actions例(Secretsとマスク)

jobs:
  plan:
    runs-on: ubuntu-latest
    env:
      TF_VAR_db_password: ${{ secrets.DB_PASSWORD }}
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init -input=false
      - run: terraform plan -input=false -no-color
      # 自動化で値が必要な場合は要注意。-jsonは値を含み得るため、出力先は限定
      - run: |
          terraform output -json \
            | jq -r '.db_password_masked.value' \
            | awk '{print "::add-mask::" $0}'   # 取り回し前にマスク

よくある落とし穴と確認手順

sensitive値を含む式は、原則としてsensitiveが伝播します。意図せぬ露出を避けるには、出力でsensitiveを付けるか、nonsensitive()を使わない方針を徹底します。逆に、どうしても参照側に平文が必要なときのみnonsensitive()を用います。

また、sensitive値を非sensitiveのoutputに割り当てるとエラーになります。これは暗黙の露出を防ぐ安全装置です。

  • 文字列結合・format()・テンプレートでも基本は伝播するため安心だが、nonsensitive()を混ぜると露出する。
  • ツール連携時の- json系コマンドは最も漏えいしやすい箇所。配送先と保管先を限定。
  • stateに残る過去の値は簡単には抹消できない。ローテーションと鍵更新を前提に。

意図せぬ露出のブロックと明示的な露出の例

# NG: sensitive値を非sensitiveの出力に割り当て(計画時にエラー)
# output "leak" {
#   value     = var.db_password        # varはsensitive=true
#   sensitive = false
# }

# OK: マスクされたまま出力
output "db_password_safe" {
  value     = var.db_password
  sensitive = true
}

# 明示的に露出(本当に必要な場合のみ)
output "db_password_plain" {
  value     = nonsensitive(var.db_password)
  sensitive = false
}

問題で確認

Associate

問題 1

Terraformでvariableにsensitive = trueを設定した場合の正しい説明はどれか。

  1. CLIの人間向け出力では値がマスクされるが、stateには平文として保存される可能性がある
  2. stateにも自動的に暗号化されて保存されるため、バックエンドの設定は不要である
  3. すべてのプロバイダが自動的にその属性を機微扱いし、値は計画にも保存にも一切現れない
  4. terraform output -jsonは値を常に省略し、フラグのみを返すため安全である

正解: A

sensitiveは表示マスクの制御であり暗号化ではありません。人間向けのCLI表示はマスクされますが、stateには値が保存されます。暗号化・アクセス制御はバックエンド側で行う必要があります。-json出力やプロバイダ挙動についても、値が含まれる/ロギングされない保証はありません。

よくある質問

sensitiveを付ければCIのログに絶対出ませんか?

Terraformの人間向け出力はマスクされますが、-json出力や外部ツールのログ、詳細ログ(TF_LOG)などで露出する可能性があります。CIではSecretsストア、マスク規則、限定的なアーティファクト公開を組み合わせて保護してください。

stateに残った過去のパスワードを消したいのですが?

履歴の完全抹消は難しいため、原則はローテーションで対応します。不要な出力は削除し、必要に応じてterraform state rmで対象リソースをstateから除外後に再作成します。remote backendのバージョニング履歴はバックエンド側の機能(削除/リーガルホールド解除等)に依存します。

sensitive()関数とvariableのsensitive属性はどちらを使うべき?

入力値に対してはvariableのsensitiveを、計算・合成された値(localsやテンプレート結果など)にはsensitive()を使います。出力での露出が必要な場合のみnonsensitive()で明示的に剥がしてください。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.