1. 概要
sensitive = trueとは何か、なぜ必要か- variable・output・localsでのsensitive設定
- stateファイルへの保存とその注意点
nonsensitive()関数の使い方- 機密値の安全な管理パターン
Terraformでsensitive = trueを設定すると、パスワード・APIキー・秘密鍵などの機密値がterraform plan・applyの出力でマスクされます。ただし、stateファイルには平文で保存されるという点を理解して使うことが重要です。
2. variableでsensitiveを設定する
variableブロックにsensitive = trueを設定することで、その変数を使用する箇所の出力がすべてマスクされます。
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 = "RDSマスターパスワード"
type = string
sensitive = true # ← これでマスク
}
variable "db_username" {
description = "RDSマスターユーザー名"
type = string
sensitive = true
}
resource "aws_db_instance" "main" {
identifier = "${var.environment}-mysql"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.micro"
allocated_storage = 20
storage_encrypted = true
username = var.db_username
password = var.db_password
skip_final_snapshot = true
tags = {
Name = "${var.environment}-mysql"
Environment = var.environment
ManagedBy = "terraform"
}
}
terraform plan実行時の出力:
+ resource "aws_db_instance" "main" {
+ identifier = "dev-mysql"
+ username = (sensitive value)
+ password = (sensitive value)
...
}
3. outputでsensitiveを設定する
出力値に機密情報を含む場合はoutputブロックにもsensitive = trueを設定します。
output "db_endpoint" {
description = "RDSエンドポイント"
value = aws_db_instance.main.endpoint
# sensitiveではない(エンドポイントは公開してよい情報)
}
output "db_password" {
description = "RDSパスワード(機密)"
value = aws_db_instance.main.password
sensitive = true # ← 出力もマスク
}
sensitive = trueのoutputはterraform outputコマンドでもマスクされます。
$ terraform output
db_endpoint = "dev-mysql.xxx.ap-northeast-1.rds.amazonaws.com:3306"
db_password = <sensitive>
値を確認したい場合は-jsonフラグを使います(アクセスできる人のみ):
$ terraform output -json db_password
"my-secret-password"
4. localsでsensitiveを扱う
local値はsensitiveな変数を参照すると自動的にsensitiveになります。明示的に設定することも可能です(Terraform 1.9以降)。
locals {
# db_passwordがsensitiveなため、connection_stringも自動的にsensitive
connection_string = "mysql://${var.db_username}:${var.db_password}@${aws_db_instance.main.endpoint}"
# Terraform 1.9以降: 明示的にsensitiveを設定
api_config = sensitive({
endpoint = "https://api.example.com"
key = var.api_key
})
}
5. stateファイルへの保存
sensitive = trueはplanやapplyの出力をマスクするだけです。stateファイルには平文で保存されます。
# terraform.tfstate の中身(実際は平文)
{
"resources": [{
"values": {
"password": "my-secret-password" ← 平文で保存される
}
}]
}
このため、stateファイルの保護が非常に重要です。
| 対策 | 方法 |
|---|---|
| stateを暗号化して保存 | S3バックエンド + SSE-S3/SSE-KMS |
| stateへのアクセス制限 | S3バケットポリシーでIAM制限 |
| ローカルのstateを使わない | リモートバックエンドを必ず使う |
| CI/CDでの機密値管理 | AWS Secrets Manager・GitHub Actions Secretsを活用 |
6. nonsensitive() — sensitiveを解除する
nonsensitive(value)を使うと、sensitiveフラグを明示的に解除できます。機密値が安全に加工されたと確信できる場合のみ使用します。
variable "api_key" {
type = string
sensitive = true
}
locals {
# キーをハッシュ化してsensitiveを解除(ハッシュ値は公開してよい)
api_key_hash = nonsensitive(sha256(var.api_key))
}
output "api_key_hash" {
value = local.api_key_hash # sensitiveではない
}
7. 関連記事
- variable(入力変数)の使い方 — 型・バリデーション・デフォルト値
- output(出力値)の使い方 — 定義・参照・sensitiveオプション
- backend — stateファイルの保存場所を設定する — S3バックエンドで暗号化
- tfvarsファイル — 機密値をtfvarsで管理する方法
- issensitive / nonsensitive の使い方
- ephemeral変数 — 一時的な機密値(1.10+)
8. まとめ
sensitive = trueはplan/apply出力のマスクのみで、stateには平文保存されるvariable・output・locals(Terraform 1.9以降で明示設定可能)に設定できる- sensitiveな変数を参照するlocal値は自動的にsensitiveになる
- stateファイルは必ずリモートバックエンド + 暗号化で保護する
nonsensitive()は加工済みの安全な値にのみ使用する
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/values/variables#suppressing-values-in-cli-output