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値の流れとマスク箇所
# 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()で剥がします。
| 機能 | 主な目的 | 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
}人間向けのterraform plan/applyやterraform outputは、sensitive値をマスクします。terraform consoleではデフォルトで(sensitive value)と表示され、nonsensitive()で明示的に露出させるまで値は見えません。
terraform output -jsonは自動化向けで、値そのものをJSONに含めつつ、"sensitive": trueのフラグを付けます。ツール連携時は取り扱いに十分注意してください。
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" # 値が含まれる想定。保護が必要
}Terraformはstateにリソース属性の最終値を保持します。sensitiveであってもstateからは消えません。ローカルstateはファイル権限で守り、チーム利用では暗号化とアクセス制御が整ったremote backendを使います。
S3やGCS、Azure Storageなどのバックエンドは、サーバサイド暗号化やKMS連携が利用可能です。加えて、厳密なIAMと監査ログ、バージョニング・リーガルホールド等で漏えい時の影響を抑えます。
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では、変数は環境変数TF_VAR_やCIのSecrets機能から渡し、tfvarsファイルをリポジトリに含めない運用が基本です。terraform output -jsonの扱いには特に注意し、ログやアーティファクトで露出しないようマスキング・アクセス制御を行います。
高詳細ログ(TF_LOG=DEBUG/TRACE)は不用意に機微値を含み得ます。必要時のみ一時的に使い、出力先は限定・破棄を徹底します。
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に割り当てるとエラーになります。これは暗黙の露出を防ぐ安全装置です。
意図せぬ露出のブロックと明示的な露出の例
# 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を設定した場合の正しい説明はどれか。
正解: 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()で明示的に剥がしてください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...