Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Upravlenie sekretami v vashem kode terraform 2
Dev48

© 2026 · All rights reserved.

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

Источник: Gruntwork

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

Источник: Gruntwork

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

27 сентября 2026 г.•Обновлено: 27 сентября 2026 г.

Один из самых частых вопросов, которые нам задают по поводу использования 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.

← Все статьи

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

Все →
Новый навык обнаруживает риски ИИ-агентов, устраняет их и доказывает эффективность исправлений
Microsoft

Новый навык обнаруживает риски ИИ-агентов, устраняет их и доказывает эффективность исправлений

Сообщества вокруг дата-центров Amazon: что происходит рядом с центрами обработки данных по всей территории США
Amazon

Сообщества вокруг дата-центров Amazon: что происходит рядом с центрами обработки данных по всей территории США

Приложение GitHub Copilot для начинающих: как создавать собственные рабочие процессы с помощью холстов
GitHub Actions

Приложение GitHub Copilot для начинающих: как создавать собственные рабочие процессы с помощью холстов

Microsoft объединяет бизнес-ИИ в единое приложение в попытке конкурировать с AnthropicПресса
Microsoft

Microsoft объединяет бизнес-ИИ в единое приложение в попытке конкурировать с Anthropic

Повышение производительности сайта за счет отправки большего объема CSS
GitHub Actions

Повышение производительности сайта за счет отправки большего объема CSS

От Opus 5 к Opus 5.5: более качественные исправления при снижении затрат на 58% в SonarQube Remediation Agent
SonarSource

От Opus 5 к Opus 5.5: более качественные исправления при снижении затрат на 58% в SonarQube Remediation Agent

Ещё от Gruntwork

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

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

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

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

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

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

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

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

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

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