Управление секретами: основы и типы

Рейтинг: 67.6% · 8 голосов
Подробный курс по Terraform и OpenTofu на примерах Yandex Cloud: ресурсы и провайдеры, состояние и бэкенды, модули, циклы и условия HCL, секреты и Lockbox, тестирование, CI/CD и командная работа. С актуализацией на 2026 (Terraform 1.3-1.10, OpenTofu).
Ответить
Аватара пользователя
Vlad_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Управление секретами: основы и типы

Сообщение Vlad_DevOps »

Оглавление курса (47)
  1. Что такое инфраструктура как код и зачем она нужна
  2. Категории инструментов IaC: чем отличаются Ansible, Packer, Kubernetes и Terraform
  3. Чем Terraform отличается от Ansible, Pulumi и CloudFormation
  4. Как работает Terraform под капотом и кто такой OpenTofu
  5. Установка Terraform и OpenTofu, подготовка Yandex Cloud
  6. Первый ресурс: разворачиваем виртуальную машину в Yandex Cloud
  7. Веб-сервер на ВМ: метаданные, user-data и группы безопасности
  8. Переменные ввода и выходные значения в Terraform
  9. Кластер ВМ: группа экземпляров Yandex Compute Instance Group
  10. Балансировщик нагрузки: Application Load Balancer в Yandex Cloud
  11. Состояние Terraform: что такое tfstate и чем опасен локальный файл
  12. Удалённое хранилище состояния: бэкенд на Yandex Object Storage
  13. Изоляция состояния: рабочие области против раскладки по папкам
  14. Источники данных и terraform_remote_state: связываем компоненты
  15. Модули Terraform: переиспользуем инфраструктуру
  16. Входные, локальные и выходные переменные модуля
  17. Версионирование модулей и подводные камни
  18. Циклы в Terraform: параметр count
  19. Циклы в Terraform: for_each по множествам и картам
  20. Выражения for и строковые директивы
  21. Условная логика: count-трюк, for_each и директива if
  22. Встроенные функции, типы и выражения HCL
  23. Развёртывание без простоя: create_before_destroy
  24. Подводные камни Terraform и рефакторинг с блоком moved
  25. Управление секретами: основы и типы (вы здесь)
  26. Инструменты управления секретами: Yandex Lockbox, Vault, SOPS
  27. Аутентификация провайдера и секреты: сервисные аккаунты и OIDC
  28. Секреты в ресурсах и состоянии, ephemeral-значения
  29. Провайдеры Terraform: установка, версии, required_providers
  30. Несколько копий одного провайдера: alias и мультизона
  31. Несколько провайдеров и аккаунтов: configuration_aliases
  32. Terraform, Docker и Kubernetes: Managed Kubernetes в Yandex Cloud
  33. Код Terraform промышленного уровня: почему это долго
  34. Мелкие компонуемые модули вместо монолита
  35. Тестируемые модули и проверки: validation, precondition, postcondition
  36. Версионирование, публикация модулей и Terragrunt
  37. Ручное тестирование Terraform и очистка ресурсов
  38. Автоматические тесты на Terratest: модульные тесты
  39. Интеграционные и сквозные тесты, пирамида тестирования
  40. Нативный terraform test и статический анализ
  41. Внедрение Terraform в команде: процессы и культура
  42. Конвейер развёртывания прикладного кода
  43. Конвейер инфраструктурного кода и золотое правило Terraform
  44. Стиль, ревью и CI/CD-инструменты: Atlantis, TACOS, policy as code
  45. Что нового в Terraform 1.3-1.10: моды, импорт, провайдер-функции, Stacks
  46. OpenTofu в 2026: чем живёт форк и как мигрировать
  47. Сертификация HashiCorp Terraform Associate и карьера
Представь ситуацию. Ты пишешь конфигурацию для базы данных, тебе нужен пароль, ты не долго думая вставляешь его прямо в HCL: password = "SuperSecret123". Работает же. Коммитишь, пушишь, идёшь пить кофе. А через полгода этот репозиторий форкает стажёр, выкладывает на свой публичный GitHub "для портфолио", и твой продакшн-пароль уже индексируется поисковиками. Это не страшилка из методички, это рутина инцидент-реагирования. Секреты в инфраструктуре как код - тема, на которой обжигаются примерно все, кто впервые трогает terraform.

В этом уроке мы не будем настраивать конкретный менеджер секретов - это будет дальше. Сейчас задача шире: понять, какие секреты вообще живут в инфра-коде, по каким правилам с ними обращаться и почему даже идеально написанный конфиг не спасает от утечки через state. Это фундамент, без которого любой инструмент - просто кнопка, на которую ты жмёшь, не понимая зачем.

Какие секреты живут в инфраструктуре

Когда говорят "секрет", новичок обычно думает про пароль от базы. На деле в реальном проекте секретов целый зоопарк, и каждый тип утекает по-своему:
  • Пароли БД - классика. PostgreSQL, MySQL, Redis с паролем - всё это надо где-то хранить и как-то передавать в ресурсы.
  • API-ключи - доступ к внешним сервисам: платёжки, почтовые рассыльщики, S3-совместимые хранилища, мониторинг. Утёкший ключ к платёжке - это уже не "ой", это деньги.
  • Токены провайдера - тот самый OAuth-токен или сервисный ключ, которым terraform yandex cloud аутентифицируется в облаке. Самый жирный секрет: с ним можно поднять и снести вообще всю твою инфраструктуру.
  • TLS-сертификаты и приватные ключи - публичный сертификат не секрет, а вот приватный ключ к нему - очень даже. Перепутать эти две сущности - популярная ошибка.
  • SSH-ключи - приватные ключи для доступа на виртуалки. Публичную часть спокойно кладёшь в metadata инстанса, приватную - бережёшь как зеницу ока.
Объединяет их одно: если такой кусок данных увидит не тот человек, у тебя проблема. Поэтому к секретам применяют другую гигиену, чем к обычным переменным вроде имени зоны доступности или числа CPU.

Изображение

Три вопроса, на которые надо ответить про каждый секрет

Любую схему работы с секретами в iac удобно раскладывать на три вопроса. Если ты честно ответил на все три - у тебя есть стратегия, а не "как-нибудь спрячем".

1. Как хранить? Варианты по нарастанию зрелости: переменные окружения, отдельный незакоммиченный файл, и наконец менеджер секретов (HashiCorp Vault, Yandex Lockbox, облачные KMS). Файл проще, менеджер - правильнее, потому что он даёт версионирование, аудит и централизованный отзыв.

2. Как считывать? Секрет должен попадать в конфигурацию в момент исполнения, а не лежать в исходниках. Это либо передача через переменные (var с пометкой sensitive), либо чтение из менеджера через data-источник. Идея одна: код описывает, ОТКУДА взять секрет, но не сам секрет.

3. Кому доступ? Самый недооценённый вопрос. Мало спрятать секрет - надо ответить, кто и что может с ним сделать. Доступ к хранилищу секретов и доступ к state-файлу - это два отдельных контура, и оба надо ограничивать по принципу минимальных привилегий.

Антипаттерн номер один: секрет в коде и в git

Повторим жирным шрифтом, потому что это самая частая и самая дорогая ошибка: не клади секреты в исходный код и тем более не коммить их в git. Вот как НЕ надо:

Код: Выделить всё

# ПЛОХО. Так делать нельзя.
resource "yandex_mdb_postgresql_user" "app" {
  cluster_id = yandex_mdb_postgresql_cluster.main.id
  name       = "app_user"
  password   = "Qwerty12345"   # секрет открытым текстом, да ещё и в git
}
Коварство git в том, что у него длинная память. Даже если ты потом удалишь строку отдельным коммитом, пароль навсегда останется в истории. Любой, у кого есть клон репозитория, достанет его командой git log. Поэтому "ой, я уже закоммитил" решается не удалением строки, а немедленной ротацией секрета: меняешь пароль, отзываешь ключ, и только потом чистишь историю.

Как надо хотя бы на минимальном уровне - вынести секрет во входную переменную и пометить её чувствительной:

Код: Выделить всё

variable "db_password" {
  type      = string
  sensitive = true   # terraform не покажет значение в выводе plan/apply
}

resource "yandex_mdb_postgresql_user" "app" {
  cluster_id = yandex_mdb_postgresql_cluster.main.id
  name       = "app_user"
  password   = var.db_password
}
А само значение передаёшь снаружи - через переменную окружения TF_VAR_db_password или через защищённую CI-переменную. В репозиторий не попадает ничего секретного: только описание, что переменная нужна. Флаг sensitive = true прячет значение из вывода terraform plan и terraform apply, но - внимание - НЕ убирает его из state. И это подводит нас к главному подвоху всего урока.

Секреты всё равно попадают в state

Вот мысль, которую новички пропускают, а потом ловят инцидент. terraform state хранит реальные значения всех ресурсов, включая секретные. Пароль, который ты аккуратно передал через sensitive-переменную, в state-файле лежит открытым текстом. Никакого волшебного шифрования "из коробки" в обычном terraform нет: state - это просто JSON, и пароль БД в нём как на ладони.

Логика проста: чтобы построить план изменений, terraform должен знать текущее состояние мира. А пароль - это часть состояния. Поэтому он там и оседает. Sensitive влияет только на ВЫВОД в консоль, файл состояния это не трогает.

Отсюда два железных следствия, которые надо запомнить навсегда:
  • Шифруй state. Храни его в backend, который шифрует данные на стороне сервера. Для terraform yandex cloud это бакет Object Storage с включённым шифрованием через KMS. Отдельно отмечу: OpenTofu (открытый форк, на 2026 год актуальная ветка 1.12.x) умеет шифровать state прямо на клиенте, до отправки в backend - функция называется state encryption и в самом terraform её до сих пор нет. Это один из весомых аргументов в пользу opentofu, если безопасность state для тебя приоритет.
  • Ограничивай доступ к state. Бакет с состоянием - это не место для read-доступа всей команды. Кто читает state, тот читает все пароли проекта. Доступ только сервисному аккаунту CI и паре ответственных людей.
Минимальный backend с удалённым шифрованным state в Object Storage выглядит так:

Код: Выделить всё

terraform {
  backend "s3" {
    endpoints = {
      s3 = "https://storage.yandexcloud.net"
    }
    bucket = "my-tfstate"
    key    = "prod/terraform.tfstate"
    region = "ru-central1"

    skip_region_validation      = true
    skip_credentials_validation = true
  }
}
Ключи доступа к самому бакету при этом, разумеется, тоже не пишутся в код, а передаются через окружение (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY со статическим ключом сервисного аккаунта).

Обзор подходов: куда мы движемся

Если разложить все способы по лесенке зрелости, получится примерно так:
  • Уровень 0. Секрет в коде. Это не уровень, это инцидент. Забудь.
  • Уровень 1. Sensitive-переменные плюс передача через окружение или CI. Уже прилично для пет-проекта, но секрет всё ещё руками передаётся и оседает в state.
  • Уровень 2. Менеджер секретов. Секреты лежат в специализированном хранилище, terraform читает их через data-источник в момент apply, доступ рулится IAM-политиками, есть аудит и версии.
Для Yandex Cloud менеджер секретов - это Lockbox, к которому мы вплотную подойдём в следующих уроках. Чтобы ты уже сейчас увидел направление, вот как выглядит чтение существующего секрета из Lockbox через data-источник (значение нигде в коде не хранится, оно подтягивается из облака):

Код: Выделить всё

data "yandex_lockbox_secret_version" "db" {
  secret_id = "e6q..."   # идентификатор секрета в Lockbox
}

locals {
  db_password = [
    for entry in data.yandex_lockbox_secret_version.db.entries :
    entry.text_value if entry.key == "password"
  ][0]
}
Обрати внимание: в HCL нет ни одного символа самого пароля. Есть только адрес, по которому его взять. Это и есть та самая зрелая модель - код знает откуда, но не знает что. Правда, и тут секрет в итоге окажется в state после apply, так что правило про шифрование и ограничение доступа к state никуда не девается даже с Lockbox. Менеджер решает вопросы хранения, ротации и аудита, но магически вычистить пароль из файла состояния он не может.

Типичные грабли
  • Думать, что sensitive = true шифрует секрет. Нет. Он только прячет значение в консоли. В state - открытый текст.
  • Закоммитить terraform.tfstate в git. Звучит дико, но в публичных репозиториях такого добра полно. State всегда в .gitignore, всегда в удалённом backend.
  • Положить terraform.tfvars с реальными секретами в репозиторий. Файл tfvars - такой же исходник. Реальные значения - только в .tfvars.local, который в .gitignore, или в окружении.
  • Путать публичный и приватный ключ. Публичную часть SSH-ключа кладёшь в metadata инстанса спокойно. Приватную - никогда в код.
  • Раздать read на state-бакет всей команде. Это равносильно тому, чтобы раздать все пароли проекта. Доступ к state = доступ к секретам.
Мини-лаба

Руками, без облака, минут на пятнадцать:
  • Заведи переменную db_password с sensitive = true и любой ресурс, который её использует (можно фейковый local_file для теста).
  • Передай значение через export TF_VAR_db_password=... и выполни terraform plan apply. Убедись, что в выводе вместо значения стоит (sensitive value).
  • Теперь открой terraform.tfstate любым редактором и найди свой пароль открытым текстом. Прочувствуй этот момент - это и есть главный урок про state.
  • Добавь terraform.tfstate и *.tfvars в .gitignore. Проверь через git status, что они не отслеживаются.
Контрольные вопросы
  • Назови минимум пять типов секретов, которые встречаются в инфра-коде.
  • Что на самом деле делает sensitive = true, а чего НЕ делает?
  • Почему секреты оказываются в terraform state и какие два правила из этого следуют?
  • Чем чтение секрета из менеджера (Lockbox) через data-источник лучше передачи через переменную окружения?
Итог: что запомнить

Секрет в коде и в git - это инцидент, а не стиль. Любой секрет проходит через три вопроса: как хранить, как считывать, кому доступ. Флаг sensitive прячет значение только в консоли, но не в state - а в state секреты лежат открытым текстом всегда, поэтому state обязательно шифруют и жёстко ограничивают к нему доступ. Лесенка зрелости ведёт от переменных окружения к менеджеру секретов, и для Yandex Cloud этот менеджер - Lockbox, которым мы займёмся вплотную дальше.
👍2 ❤️3 🔥 😄 🤔
Аватара пользователя
mojemo
Сообщения: 2
Зарегистрирован: 29 май 2026, 13:02

Re: Управление секретами: основы и типы

Сообщение mojemo »

Блин, реально пошёл и открыл свой tfstate после абзаца про state - там пароль от постгреса лежит как ни в чём не бывало. Думал sensitive меня спасает, а он только в консоли прячет. Спасибо, починил доступ к бакету.
👍 ❤️ 🔥 😄 🤔1
Аватара пользователя
dockeruser
Сообщения: 1
Зарегистрирован: 31 май 2026, 09:01

Re: Управление секретами: основы и типы

Сообщение dockeruser »

А подскажи, если я уже закоммитил ключ месяц назад и заметил только сейчас - чистить историю git помогает или поздно? Из урока понял что главное сначала ротировать сам ключ, но хочу убедиться что верно.
👍1 ❤️ 🔥 😄 🤔1
Ответить
← Предыдущая глава
Подводные камни Terraform и рефакторинг с блоком moved
Следующая глава →
Инструменты управления секретами: Yandex Lockbox, Vault, SOPS

Все главы курса «Terraform: инфраструктура как код на Yandex Cloud»

Поделиться темой: ✈ Telegram VK
Похожие запросы: управление секретами в terraform yandex lockbox

Вернуться в «Terraform: инфраструктура как код на Yandex Cloud»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость