linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/kb/Security/tf-sensitive

kb/security ── Security ── intermediate

sensitive в Terraform: про логи, не про шифрование

`sensitive = true` у variable/output/local прячет значение от CLI-вывода и логов. В state и .tfstate.backup значение **открытое**. Это redaction, не encryption. Реально секретное, храни в Secrets Manager или Vault, читай через data-source, плана не сохраняй в артефактах. `nonsensitive()` нужен в редких случаях когда sensitive-флаг каскадируется и мешает.

view as markdownaka: terraform-sensitive, sensitive-variable, sensitive-output

Что делает sensitive

Помеченный sensitive = true объект:

  1. Не показывается в CLI. terraform plan пишет (sensitive value) вместо реального значения.
  2. Не показывается в terraform output. Чтобы увидеть, нужен -raw или -json явно (warning'ом).
  3. Каскадируется. Если в local'е есть sensitive-значение, весь local становится sensitive. Это «заражение» защищает от случайных протечек через output local.something.

Что НЕ делает:

  • Не шифрует state. В terraform.tfstate значение лежит открыто. Прочитать может любой с доступом к файлу.
  • Не шифрует backup. *.tfstate.backup после каждой apply, то же самое.
  • Не маскирует в plan-файле. plan.tfplan, бинарь, но terraform show plan.tfplan развернёт его и покажет всё.
  • Не маскирует в TF_LOG=DEBUG. Debug-лог показывает HTTP-запросы, включая payloads, там видно всё, что отправляется провайдеру.

Sensitive, это udit-defence. Защита от случайного terraform output | paste-in-slack. Не защита от инсайдера, имеющего доступ к state.

Объявление

Variable:

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

Output:

hcl
output "connection_string" {
  value     = "postgres://user:${var.db_password}@${aws_db_instance.main.address}/db"
  sensitive = true
}

Если value в output упоминает sensitive-источник, но sensitive = true не указан, Terraform упадёт с ошибкой «output … depends on sensitive value, set sensitive = true». Это страховка.

Local:

hcl
locals {
  full_url = "https://api.example.com/${var.api_token}"
  # full_url автоматически sensitive, заразился от api_token
}

Resource attribute (некоторые провайдеры так помечают атрибуты, это уже schema-уровень):

hcl
resource "random_password" "user" {
  length = 24
}
# random_password.user.result, auto-sensitive (so документация и провайдер)

nonsensitive() когда стрелка перепрыгнула

Иногда нужно достать публично-частную часть из sensitive-значения. Например, aws_db_instance.main.endpoint сам не sensitive, но из-за того что build'ится через format(..., aws_db_instance.main.address, ...) весь результат становится sensitive, и Terraform отказывается это отдавать в plan-выводе.

hcl
output "host" {
  value = nonsensitive(aws_db_instance.main.address)
}

nonsensitive(x) снимает флаг. Используй сознательно, это explicit ack «знаю что делаю». Никогда не оборачивай в nonsensitive то, что реально секретное.

Sensitive в plan-файле

bash
terraform plan -out=plan.tfplan
terraform show plan.tfplan

show plan.tfplan показывает всё что в плане, включая значения sensitive-полей и переменных. Если ты экспортируешь plan.tfplan как CI-артефакт между jobs, он содержит секреты.

Это значит:

  • Не хранить plan.tfplan дольше нужного. В GitHub Actions actions/upload-artifact имеет retention; ставь минимум, удаляй после apply.
  • Не публиковать plan-файлы. Даже в private-репо, кому-то может быть видно по правам.
  • Шифруй артефакт при передаче. Если pipeline сложный, sops, age, или нативные artifact-secrets провайдера.

См. tf-plan-apply-ci и tf-secrets-in-state.

Реально секретное, не в variable

Антипаттерн:

hcl
variable "db_password" {
  sensitive = true
  default   = "supersecret"  # НИКОГДА
}

Дефолт в HCL = в git = read-only-доступ к репо = доступ к паролю. Это не «secret in variable», это «secret in code».

Правильный паттерн, читать секрет из менеджера на каждом apply:

hcl
data "aws_secretsmanager_secret_version" "db" {
  secret_id = "prod/db/master"
}
resource "aws_db_instance" "main" {
  # ...
  password = data.aws_secretsmanager_secret_version.db.secret_string
}

Секрет ротируется в Secrets Manager, Terraform на следующем apply заберёт новый. См. tf-secrets-in-state.

Какие атрибуты провайдеры помечают sensitive автоматически

Resource/DataАтрибутПомечен sensitive
random_passwordresultда
tls_private_keyprivate_key_pemда
aws_db_instancepasswordда (если set)
aws_secretsmanager_secret_versionsecret_stringда
aws_iam_access_keysecret, ses_smtp_password_v4да
aws_kms_data_keyplaintext, ciphertext_blobоба

Это не полный список, открой docs провайдера, ищи иконку 🔒 или метку «(sensitive)».

Подводные камни

  • State не шифруется sensitive-флагом. Любой с доступом к terraform.tfstate видит все sensitive-значения. Шифрование, задача backend'а: S3 SSE, encryption_at_rest у Terraform Cloud.

  • TF_LOG=DEBUG течёт. Логи провайдера показывают HTTP-payloads. Никогда не публикуй DEBUG-логи в issue/Slack, там сырые секреты.

  • sensitive = true нельзя поменять без replace. Из non-sensitive в sensitive, ОК, Terraform проглотит. В обратную сторону, ему нужно оценить, не утечёт ли значение через output, и часто он требует apply на промежуточном шаге.

  • На output без sensitive ошибка cryptic. Если output упоминает sensitive-значение, забыл sensitive = true, будет «output value … is sensitive but the sensitive marker is not set». Это reminder добавить флаг, не баг.

  • Sensitive не работает на провайдер-конфиг. provider "aws" { access_key = var.x }, Terraform НЕ умеет sensitive-маркировать сам provider конфиг. Передавай через env (AWS_ACCESS_KEY_ID), не через переменную.

  • nonsensitive() отключает защиту полностью. Не вставляй «на всякий случай чтобы plan читался», потеряешь redaction там, где он был нужен.

§ команды

bash
terraform output -json

Sensitive-значения видны (явный opt-in). Warning в stderr.

bash
terraform output -raw db_password

Print raw value. Single output только.

bash
terraform show -json terraform.tfstate | jq '.values.outputs'

Все outputs из state, включая sensitive-значения.

bash
terraform plan -out=plan.tfplan && terraform show plan.tfplan

Plan-файл показывает sensitive: обращайся с ним как с секретом.

§ см. также

  • tf-secrets-in-stateСекреты и Terraform state: где хранить и как читатьState содержит всё что прошло через apply, пароли, ключи, токены в открытом виде. Решения: хранить секреты в Secrets Manager / Vault / KMS, читать через data-source, шифровать backend (S3 SSE-KMS), OIDC вместо access-keys для CI. «sensitive=true», про логи, не про шифрование.
  • tf-variableБлок variable: вход в конфигурациюvariable, параметр, который принимает значение снаружи (CLI, env, .tfvars). Объявляешь в HCL: type, default, description, validation. Используешь как var.name. Нужен чтобы убрать хардкод и переиспользовать один HCL для разных окружений.
  • tf-outputБлок output: что Terraform возвращает наружуoutput, это значение, которое Terraform показывает после apply и сохраняет в state. Используется для (а) показать пользователю ID/ARN созданного ресурса, (б) передать значения между модулями, (в) скриптам через terraform output -raw.
  • tf-localslocals: вычисляемые внутренние именаlocals: блок с именами, видимыми только внутри HCL (не вход, не выход). Удобны для DRY: один раз сосчитал общий префикс или теги: везде используешь через local.x. Не путать с variable (вход) и output (выход).
  • tf-checkovCheckov: статический анализ HCLCheckov, Python-сканер от Prisma Cloud, проверяет `.tf` и `plan.json` против ~2000 встроенных правил (CKV_AWS_*, CKV_K8S_*, etc.). Запускается на HCL до plan'а (быстрее) или на JSON-plan (богаче, видит вычисленные значения). Suppressions делаются комментарием в HCL или в файле конфигурации; baseline-файл фиксирует найденные issues как «приемлемые на сейчас», чтобы новые сразу ломали CI.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки