Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Upravlenie sekretami v vashem kode terraform 2
Dev48
info@dev48.org+375 29 320-40-96WhatsApp@isky_by

© 2026 · Все права защищены.

Управление секретами в вашем коде Terraform

Источник: Gruntwork•27 сентября 2026 г. в 09:21

Управление секретами в вашем коде Terraform

Управление секретами в коде Terraform: обработка паролей и ключей API с помощью переменных окружения, зашифрованных файлов (таких как KMS и SOPS) и хранилищ секретов вроде Vault.

Один из самых частых вопросов, которые нам задают по поводу использования Terraform для управления инфраструктурой как кодом, касается того, как обрабатывать такие секреты, как пароли, ключи API и другие конфиденциальные данные. Например, вот фрагмент кода Terraform, который можно использовать для развертывания MySQL с помощью Amazon RDS:

Обратите внимание, что Terraform требует от вас настройки двух секретов — имени пользователя и пароля, которые являются учетными данными для основного пользователя базы данных. В этой статье я рассмотрю наиболее распространенные методы, которые можно использовать для безопасного и надежного управления такими секретами:

  • Предварительное условие №1: Не храните секреты в виде простого текста
  • Предварительное условие №2: Обеспечьте безопасность состояния Terraform
  • Метод №1: Переменные окружения
  • Метод №2: Зашифрованные файлы (например, KMS, PGP, SOPS)
  • Метод №3: Хранилища секретов (например, Vault, AWS Secrets Manager)

Предварительное условие №1: Не храните секреты в виде простого текста

Первое правило управления секретами гласит:

Не храните секреты в виде простого текста.

Второе правило управления секретами гласит:

НЕ ХРАНИТЕ СЕКРЕТЫ В ВИДЕ ПРОСТОГО ТЕКСТА.

Серьезно, не делайте этого. Например, НЕ пишите учетные данные вашей базы данных прямо в коде Terraform и не добавляйте их в систему контроля версий:

Хранение секретов в виде простого текста в системе контроля версий — ПЛОХАЯ ИДЕЯ. Вот лишь несколько причин почему:

  • Любой, у кого есть доступ к системе контроля версий, имеет доступ к этому секрету. В примере выше каждый разработчик в вашей компании имеет доступ к основным учетным данным для вашей базы данных.
  • Каждый компьютер, имеющий доступ к системе контроля версий, хранит копию этого секрета. На каждом компьютере, с которого когда-либо клонировался этот репозиторий, все еще может оставаться копия этого секрета на локальном жестком диске. Сюда входят компьютеры каждого разработчика в вашей команде, каждый компьютер, участвующий в CI (например, Jenkins, CircleCI, GitLab и т. д.), каждый компьютер, участвующий в управлении версиями (например, GitHub, GitLab, Bitbucket), каждый компьютер, участвующий в развертывании (например, все ваши предпродакшн- и продакшн-окружения), каждый компьютер, участвующий в резервном копировании (например, CrashPlan, Time Machine и т. д.), и так далее.
  • Каждая выполняемая вами программа имеет доступ к этому секрету. Поскольку секреты хранятся в виде простого текста на стольких жестких дисках, любая программа, работающая на любом из этих компьютеров, потенциально может прочитать этот секрет.
  • Отсутствует возможность аудита или отзыва доступа к этому секрету. Когда секреты хранятся на сотнях жестких дисков в виде простого текста, у вас нет возможности узнать, кто к ним обращался (нет журнала аудита), и нет способа отозвать доступ.

Короче говоря, если вы храните секреты в виде простого текста, вы предоставляете злоумышленникам (например, хакерам, конкурентам, недовольным бывшим сотрудникам) бесчисленные способы получить доступ к самым конфиденциальным данным вашей компании — например, путем компрометации системы контроля версий, любого из используемых вами компьютеров или любой программы на этих компьютерах и т. д. — и вы даже не узнаете, была ли совершена атака, и у вас не будет простого способа исправить ситуацию.

Поэтому я настоятельно рекомендую всегда хранить секреты в зашифрованном виде — и это относится ко всем секретам, а не только к тем, которые используются в Terraform! Далее в этой статье я расскажу о нескольких различных методах шифрования и дешифрования таких секретов.

Предварительное условие №2: Обеспечьте безопасность состояния Terraform

Будем надеяться, что предыдущий раздел убедил вас не хранить секреты в виде простого текста, а в последующих разделах будут показаны некоторые методы их шифрования. Однако независимо от того, какой метод вы используете для шифрования секретов на своей стороне, останется одно место, где они все равно окажутся в виде простого текста: состояние Terraform.

Каждый раз, когда вы развертываете инфраструктуру с помощью Terraform, в файл состояния записывается множество данных об этой инфраструктуре, включая все переданные вами параметры. По умолчанию это файл terraform.tfstate, который автоматически создается в папке, где вы выполнили команду terraform apply. Так что даже если вы используете один из упомянутых далее методов для безопасной передачи секретов, например учетных данных для базы данных:

Эти секреты все равно попадут в terraform.tfstate в виде простого текста! Эта проблема остается открытой уже более 6 лет, и пока нет четких планов по созданию полноценного встроенного решения. Существуют обходные пути, которые могут удалять секреты из файлов состояния, но они ненадежны и могут сломаться при любом новом релизе Terraform, поэтому я их не рекомендую.

В настоящее время, независимо от того, какой из обсуждаемых ниже методов вы в итоге выберете для управления секретами, вы также должны:

  • Хранить состояние Terraform в бэкенде, поддерживающем шифрование. Вместо хранения состояния в локальном файле terraform.tfstate, Terraform нативно поддерживает различные backends, такие как S3, GCS и Azure Blob Storage. Многие из этих бэкендов поддерживают шифрование, поэтому файлы вашего состояния будут всегда зашифрованы — как при передаче (например, по протоколу TLS), так и на диске (например, с помощью AES-256). Большинство бэкендов также поддерживают функции совместной работы (например, автоматическую отправку и получение состояния; блокировку), поэтому использование бэкенда является обязательным как с точки зрения безопасности, так и с точки зрения командной работы. Дополнительную информацию см. в разделе «Как управлять состоянием Terraform».
  • Строго контролировать доступ к вашему бэкенду Terraform. Поскольку файлы состояния Terraform могут содержать секреты, вам нужно тщательно контролировать, кто имеет доступ к бэкенду, используемому для хранения файлов состояния. Например, если вы используете S3 в качестве бэкенда, вам следует настроить политику IAM, которая предоставляет доступ к бакету S3 для продакшн-окружения только небольшой группе доверенных разработчиков (или, возможно, исключительно серверу CI, который вы используете для развертывания в продакшн).

А теперь, без лишних слов, давайте обсудим различные доступные вам методы управления секретами с помощью Terraform.

Метод №1: Переменные окружения

Этот первый метод защищает ваш код от секретов в виде простого текста благодаря встроенной в Terraform поддержке чтения переменных окружения.

Обзор

Чтобы использовать этот метод, объявите переменные для секретов, которые вы хотите передать:

Обновление от 3 декабря 2020 г.: в Terraform 0.14 появилась возможность помечать переменные как конфиденциальные (sensitive), что помогает не допускать их попадания в логи, поэтому вам следует добавить sensitive = true для обеих переменных выше!

Затем передайте переменные ресурсам Terraform, которым эти секреты необходимы:

Теперь вы можете передать значение для каждой переменной foo, установив переменную окружения с именем TF_VAR_foo. Например, вот как вы можете установить имя пользователя и пароль через окружение в Linux, Unix или Mac и запустить terraform apply для развертывания базы данных:

(Полезный совет: если у вас правильно установлена переменная окружения в терминале Bash, любая команда, начинающаяся с пробела, не будет сохраняться в истории Bash. Используйте это при установке переменных окружения с секретами, чтобы такие секреты не сохранялись на диске.)

Эта методика помогает избежать хранения секретов в виде простого текста в вашем коде, но оставляет открытым вопрос о том, как на самом деле безопасно хранить секреты и управлять ими. Так что в каком-то смысле эта методика лишь откладывает проблему на потом, в то время как другие подходы, описанные далее в этой статье, более регламентированы.

Тем не менее, чтобы не оставлять вас в полной неопределенности, если вы все же выбираете переменные окружения, самым распространенным решением для хранения секретов и управления ими является использование менеджера паролей, такого как:

  • 1Password: SaaS-инструмент, который предлагает (а) настольные и мобильные приложения для всех платформ и (б) облачную синхронизацию, позволяющую получать доступ к секретам на всех устройствах и работать в команде.
  • LastPass: SaaS-инструмент, который предлагает (а) настольные и мобильные приложения для всех платформ и (б) облачную синхронизацию, позволяющую получать доступ к секретам на всех устройствах и работать в команде.
  • pass: Инструмент с открытым исходным кодом, который следует философии Unix: это инструмент командной строки, он осуществляет ввод и вывод через текстовые потоки (т. е. stdin, stdout), а «под капотом» все хранит в виде файлов, причем каждый секрет находится в своем собственный файле, зашифрованном с помощью PGP (вы можете фиксировать эти зашифрованные файлы в системе контроля версий для командной работы).

Эти инструменты решают проблему «откладывания на потом», полагаясь на человеческую память: то есть на вашу способность запомнить пароль, который дает вам доступ к менеджеру паролей.

Пример использования pass

Давайте рассмотрим быстрый пример использования pass. Сначала вам нужно сохранить свои секреты с помощью команды pass insert:

Вы можете вывести секрет в stdout, выполнив команду pass <secret>:

Вы можете использовать эту функциональность в подпанели (subshell) для установки секретов в качестве переменных окружения, а затем вызвать terraform apply:

Преимущества этого метода

  • Секреты в виде простого текста не попадают в ваш код и систему контроля версий.
  • Простое решение для начала работы.
  • Интегрируется с большинством других решений для управления секретами: например, если в вашей компании уже есть способ управления секретами, вы, как правило, сможете заставить его работать с переменными окружения.
  • Удобство тестирования: при написании тестов для вашего кода Terraform (например, с помощью Terratest) не нужно настраивать зависимости (например, хранилища секретов), так как вы можете легко установить переменные окружения в качестве фиктивных значений.

Недостатки этого метода

  • Не все определено в самом коде Terraform. Это усложняет понимание и поддержку кода.
  • Каждый, кто использует ваш код, должен знать о необходимости выполнения дополнительных шагов: либо вручную установить эти переменные окружения, либо запустить вспомогательный скрипт.
  • Никаких гарантий или мнений относительно безопасности. Поскольку все управление секретами происходит вне Terraform, код не накладывает никаких требований безопасности, и вполне возможно, что кто-то все еще управляет секретами небезопасным способом (например, хранит их в виде простого текста).

Метод №2: Зашифрованные файлы (например, KMS, PGP, SOPS)

Второй метод заключается в шифровании секретов, сохранении шифротекста в файл и добавлении этого файла в систему контроля версий.

Обзор

Чтобы зашифровать какие-то данные, например секреты в файле, вам нужен ключ шифрования. Этот ключ сам по себе является секретом! Это создает некоторую загадку: как безопасно хранить этот ключ? Вы не можете добавить ключ в систему контроля версий в виде простого текста, так как тогда нет смысла что-либо им шифровать. Вы можете зашифровать ключ другим ключом, но тогда вам придется выяснить, где хранить этот второй ключ. Так что вы возвращаетесь к проблеме «откладывания на потом», поскольку вам все равно придется найти безопасный способ хранения ключа шифрования.

Наиболее распространенным решением этой загадки является хранение ключа в службе ключей, предоставляемой вашим облачным провайдером, такой как:

  • AWS KMS
  • GCP KMS
  • Azure Key Vault

Эти службы ключей решают проблему «откладывания на потом», полагаясь на человеческую память: в данном случае на вашу способность запомнить пароль, который дает вам доступ к вашему облачному провайдеру (или, возможно, вы сохраняете этот пароль в менеджере паролей и вместо этого запоминаете пароль от него).

Пример использования AWS KMS

Вот пример того, как вы можете использовать ключ, управляемый AWS KMS, для шифрования секретов. Сначала создайте файл с именем db-creds.yml, содержащий ваши секреты:

Примечание: НЕ добавляйте этот файл в систему контроля версий!

Затем зашифруйте этот файл с помощью команды aws kms encrypt и запишите полученный шифротекст в файл db-creds.yml.encrypted:

Теперь вы можете безопасно добавлять db-creds.yml.encrypted в систему контроля версий.

Чтобы расшифровать секреты из этого файла в коде Terraform, вы можете использовать источник данных aws_kms_secrets (для GCP KMS или Azure Key Vault вы вместо этого будете использовать источники данных google_kms_secret или azurerm_key_vault_secret соответственно):

Приведенный выше код прочитает db-creds.yml.encrypted с диска и, при условии наличия прав на доступ к соответствующему ключу в KMS, расшифрует содержимое для получения исходного YAML. Вы можете разобрать YAML следующим образом:

И теперь вы можете прочитать имя пользователя и пароль из этого YAML и передать их ресурсу aws_db_instance:

Одна из трудностей такого подхода заключается в том, что работать с зашифрованными файлами неудобно. Чтобы внести изменения, вам нужно локально расшифровать файл с помощью длинной команды aws kms decrypt, внести некоторые изменения, снова зашифровать файл с помощью другой длинной команды aws kms encrypt, и все это время быть чрезвычайно осторожным, чтобы случайно не зафиксировать открытый текст данных в системе контроля версий и не оставить его навсегда на своем компьютере. Это утомительный и подверженный ошибкам процесс, если вы не используете такой инструмент, как sops.

Пример использования AWS KMS с sops и Terragrunt

sops — это инструмент с открытым исходным кодом, созданный для того, чтобы упростить редактирование и работу с файлами, зашифрованными с помощью AWS KMS, GCP KMS, Azure Key Vault или PGP. sops может автоматически расшифровывать файл при открытии его в текстовом редакторе, поэтому вы можете редактировать файл в виде простого текста, а при сохранении этих файлов он автоматически шифрует содержимое обратно. Это избавляет от необходимости запускать длинные команды aws kms для шифрования или дешифрования данных или беспокоиться о том, что вы случайно зафиксируете секреты в виде простого текста в системе контроля версий. Вот .gif-анимация, показывающая sops в действии:

Terraform пока не имеет встроенной поддержки расшифрования файлов в формате, используемом sops. Одним из решений является установка и использование пользовательского провайдера для sops, terraform-provider-sops. Другой вариант, который я продемонстрирую здесь, — это использование Terragrunt, в который встроена нативная поддержка sops. Terragrunt — это тонкая обертка над Terraform, которая помогает удерживать ваш код Terraform DRY и поддерживаемым в актуальном состоянии (ознакомьтесь с руководством по быстрому старту для получения общего представления).

Допустим, вы использовали sops для создания зашифрованного файла YAML с именем db-creds.yml, как показано на .gif-анимации выше. Теперь в вашей конфигурации terragrunt.hcl вы можете использовать встроенную в Terragrunt функцию sops_decrypt_file для расшифрования этого файла и yamldecode для его синтаксического анализа как YAML:

Затем вы можете передать имя пользователя и пароль в качестве входных данных в ваш код Terraform:

Ваш код Terraform, в свою очередь, может читать эти входные данные через переменные:

Обновление от 3 декабря 2020 г.: в Terraform 0.14 появилась возможность помечать переменные как конфиденциальные (sensitive), что помогает не допускать их попадания в логи, поэтому вам следует добавить sensitive = true для обеих переменных выше!

И передайте эти переменные в aws_db_instance:

Преимущества этого метода

  • Храните секреты в виде обычного текста отдельно от вашего кода и системы контроля версий.
  • Ваши секреты хранятся в зашифрованном формате в системе контроля версий, поэтому они версионируются, упаковываются и тестируются вместе с остальным вашим кодом. Это помогает уменьшить количество ошибок конфигурации, таких как добавление нового секрета в одной среде (например, staging), но забывание добавить его в другой среде (например, production).
  • Работает с различными вариантами шифрования: AWS KMS, GCP KMS, PGP и т. д.
  • Все определено в коде. Не требуется никаких дополнительных ручных шагов или скриптов-оберток (хотя интеграция sops требует либо кастомного провайдера, либо инструмента-обертки, такого как Terragrunt).

Недостатки этого метода

  • Шифрование данных требует дополнительной работы. Вам приходится либо выполнять множество команд (например, aws kms encrypt), либо использовать внешний инструмент, такой как sops. Для правильного и безопасного использования этих инструментов требуется время на освоение.
  • Секреты теперь зашифрованы, но поскольку они по-прежнему хранятся в системе контроля версий, ротация и отзыв секретов затруднены. Если кто-то когда-либо скомпрометирует ключ шифрования, он сможет вернуться назад и расшифровать все секреты, которые когда-либо были им зашифрованы.
  • Возможность аудита того, кто получал доступ к секретам, минимальна. Если вы используете облачную систему управления ключами (например, AWS KMS), она, скорее всего, будет вести журнал аудита того, кто использовал ключ для расшифровки чего-либо, но вы не сможете узнать, что именно было расшифровано.
  • Менее удобно для тестирования: при написании тестов для вашего кода Terraform (например, с помощью Terratest) вам потребуется выполнить дополнительную работу по шифрованию данных для ваших тестовых сред.
  • Большинство управляемых сервисов ключей стоят небольших денег. Например, каждый ключ, хранящийся в AWS KMS, стоит 1 доллар в месяц.

Техника № 3: Хранилища секретов (например, Vault, AWS Secrets Manager)

Третий метод основан на хранении ваших секретов в специализированном хранилище секретов: то есть в базе данных, которая специально разработана для безопасного хранения конфиденциальных данных и жесткого контроля доступа к ним.

Обзор

Вот несколько более популярных хранилищ секретов, которые вы можете рассмотреть:

  • HashiCorp Vault: кроссплатформенное хранилище секретов с открытым исходным кодом.
  • AWS Secrets Manager: управляемое AWS хранилище секретов.
  • AWS Param Store: управляемое AWS хранилище данных с поддержкой шифрования.
  • GCP Secret Manager: управляемое GCP хранилище «ключ-значение».

Эти хранилища секретов решают проблему «перекладывания проблемы на потом», полагаясь на человеческую память: в данном случае на вашу способность запомнить пароль, который дает вам доступ к вашему облачному провайдеру (или несколько паролей в случае Vault, так как он использует Shamir’s Secret Sharing).

Пример использования AWS Secrets Manager

Сначала войдите в интерфейс AWS Secrets Manager, нажмите «store a new secret» и введите секреты, которые хотите сохранить:

По умолчанию используется формат JSON, как вы можете видеть на скриншоте выше. Затем присвойте секрету уникальное имя:

Нажмите «next» и «store», чтобы сохранить секрет.

Теперь в своем коде Terraform вы можете использовать источник данных aws_secretsmanager_secret_version для чтения этого секрета (для HashiCorp Vault, AWS SSM Param Store или GCP Secret Store вместо этого вы будете использовать источник данных vault_generic_secret, aws_ssm_parameter или google_secret_manager_secret_version):

Если вы сохранили данные секрета в формате JSON, вы можете использовать jsondecode для их синтаксического анализа:

И теперь вы можете использовать эти секреты в остальной части вашего кода Terraform:

Преимущества этого метода

  • Храните секреты в виде обычного текста отдельно от вашего кода и системы контроля версий.
  • Ваши секреты хранятся в специализированном хранилище секретов, которое обеспечивает шифрование и строгий контроль доступа.
  • Все определено в самом коде. Никаких дополнительных ручных шагов или скриптов-оберток не требуется.
  • Использование веб-интерфейса для хранения секретов обеспечивает удобство работы и минимальное время на освоение.
  • Хранилища секретов обычно поддерживают ротацию секретов, что полезно в случае компрометации секрета. Вы даже можете включить ротацию по расписанию (например, каждые 30 дней) в качестве превентивной меры.
  • Хранилища секретов обычно поддерживают подробные журналы аудита, которые показывают вам, кто именно и к каким данным получил доступ.
  • Хранилища секретов обычно предоставляют API, который можно легко использовать из всех ваших приложений, а не только из кода Terraform. AWS Secrets Manager даже генерирует фрагменты кода, которые показывают, как именно читать ваши секреты из приложений, написанных на Java, Python, JavaScript, Ruby, Go и т. д.:

Недостатки этого метода

  • Поскольку секреты не версионируются, не упаковываются и не тестируются вместе с вашим кодом, ошибки конфигурации более вероятны, такие как добавление нового секрета в одной среде (например, staging), но забывание добавить его в другой среде (например, production).
  • Большинство управляемых хранилищ секретов стоят денег. Например, AWS Secrets Manager взимает 0,40 доллара в месяц за каждый сохраненный секрет плюс 0,05 доллара за каждые 10 000 вызовов API для сохранения или извлечения данных.
  • Если вы используете хранилище секретов, управляемое самостоятельно, например HashiCorp Vault, вы одновременно тратите деньги на запуск хранилища (например, платите AWS за 3–5 инстансов EC2 для запуска Vault в режиме высокой доступности) и тратите время и деньги на то, чтобы ваша команда развертывала, настраивала, управляла, обновляла и мониторила хранилище.
  • Менее удобно для тестирования: при написании тестов для вашего кода Terraform (например, с помощью Terratest) вам потребуется выполнить дополнительную работу по записи данных в хранилища секретов.

Заключение

Вот основные выводы из этого поста в блоге:

  • Не храните секреты в виде открытого текста.
  • Используйте бэкенд Terraform, поддерживающий шифрование.
  • Используйте переменные среды, зашифрованные файлы или хранилище секретов для безопасной передачи секретов в ваш код Terraform. См. таблицу ниже для оценки компромиссов между этими вариантами.

Вся ваша инфраструктура. Определена как код. Примерно за день. Gruntwork.io.

← Все статьи

О чём эта статья

Ещё в разделе «Облака и инфраструктура»

Все →
Примечания к выпуску OneAgent версии 1.349
Dynatrace

Примечания к выпуску OneAgent версии 1.349

Запуск экономичных постоянно работающих агентов для мониторинга вашей среды: техническая сторона Watchers
Grafana Labs

Запуск экономичных постоянно работающих агентов для мониторинга вашей среды: техническая сторона Watchers

Когда алгоритм галлюцинирует в отделении интенсивной терапии, кто за этим следит?
Dynatrace

Когда алгоритм галлюцинирует в отделении интенсивной терапии, кто за этим следит?

На модели принятия решений приходится 26% запросов; Anthropic теперь привлекает новых клиентов в соотношении 2:1
Vercel

На модели принятия решений приходится 26% запросов; Anthropic теперь привлекает новых клиентов в соотношении 2:1

Как выявление ошибок ИИ-агентов делает их более надежными
Microsoft

Как выявление ошибок ИИ-агентов делает их более надежными

Экологичен ли ваш сайт?
Fastly

Экологичен ли ваш сайт?

Ещё от Gruntwork

Ускоренный курс по AWS: обучение на практике
Gruntwork

Ускоренный курс по AWS: обучение на практике

5 лет Gruntwork: от старта с нуля до $4,5 млн ARR
Gruntwork

5 лет Gruntwork: от старта с нуля до $4,5 млн ARR

Код инфраструктуры: 5 уроков из 300 000 строк
Gruntwork

Код инфраструктуры: 5 уроков из 300 000 строк

Gruntwork Blog | Terragrunt: Более быстрые запуск с пулом воркеров и кэшированием провайдеров
Gruntwork

Gruntwork Blog | Terragrunt: Более быстрые запуск с пулом воркеров и кэшированием провайдеров

5 лет Gruntwork: от самофинансирования до $4,5 млн ARR
Gruntwork

5 лет Gruntwork: от самофинансирования до $4,5 млн ARR