В Transcend мы очень серьезно относимся к нашей инфраструктуре и ее безопасности . Наш продукт управляет личными данными пользователей других компаний; наша инфраструктура должна быть герметичной. Мы максимально автоматизируем, чтобы снизить риски наших выпусков и обеспечить легкость контроля и аудита наших стандартов безопасности. Для достижения этих целей мы используем Terragrunt в тандеме с Terraform.
Terraform (от HashiCorp ) позволяет людям использовать код для предоставления и управления любым облаком, инфраструктурой или услугой. Terragrunt (от Gruntwork , официального партнера HashiCorp) является оберткой для бинарного файла Terraform, предоставляя мощные улучшения, начиная от более первоклассных выражений и заканчивая зависимостями модулей и встроенным кэшированием.
Лучшая практика в Terragrunt поощряет повторное использование и расширяемость модулей по умолчанию: это заставляет нас принимать хорошие технические решения, поддерживающие наши принципы безопасности и разработки.
Contents
- 1 Terragrunt имеет значительные преимущества перед Terraform
- 1.1 Явные зависимости: легко делитесь своим состоянием
- 1.2 Автоматическая генерация конфигурации Atlantis: избавляет от тяжелого труда
- 1.3 Поддержка переменных среды: не рекомендуется использовать жестко закодированные значения.
- 1.4 Generateблоки: удалить повторяющуюся конфигурацию Terraform
- 1.5 Автоматическая пометка ресурсов: универсальное применение метаданных
- 1.6 Вывод произвольных команд из переменных: упрощает использование библиотеки
- 1.7 read_terragrunt_configimports: Удалите повторяющийся код Terragrunt:
- 2 Terragrunt продолжает развиваться и совершенствоваться
- 3 С большим преимуществом и минимальным недостатком Terragrunt по-прежнему остается победителем.
Terragrunt имеет значительные преимущества перед Terraform
Первоначальной целью Terragrunt было заполнить несколько пробелов в функциональности Terraform, и он постоянно расширялся за счет новых функций. Несмотря на то, что Terraform развился для поддержки более продвинутых наборов функций , у него все еще есть возможности для улучшения. Только Terragrunt предлагает следующий богатый набор функций:
- Явные зависимости: легко делитесь своим состоянием
- Автоматическая генерация конфигурации Atlantis: избавляет от тяжелого труда
- Поддержка переменных среды: не рекомендуется использовать жестко закодированные значения.
Generate
блоки: удалить повторяющиеся Terraform- Автоматическая пометка ресурсов: универсальное применение метаданных
- Вывод произвольных команд из переменных: упрощает использование библиотеки
read_terragrunt_config
imports: устраните повторяющийся код Terragrunt.
Явные зависимости: легко делитесь своим состоянием
Чтобы модули Terraform можно было использовать повторно, их необходимо настраивать. Явные зависимости Terragrunt — самый эффективный способ добиться этого.
Хотя источник данных удаленного состояния Terraform позволяет передавать output
значения между модулями, его использование может привести к сложному и многословному коду. Кроме того, это делает ваши модули менее пригодными для повторного использования в случаях, когда у вас разные конфигурации состояний, и дает мало указаний читателям вашего кода относительно того, откуда берутся значения.
Terragrunt предлагает альтернативу в виде явных dependency
блоков, которые намного мощнее. Вот пример использования зависимостей с Terragrunt для настройки базы данных на AWS внутри существующего виртуального частного облака (VPC) с существующей группой безопасности (виртуальным брандмауэром):
Здесь можно отметить много интересных вещей:
Зависимости Terragrunt определяют конфигурацию своего состояния только один раз.
В Terraform я должен определить зависимости, а затем в каждом отдельном модуле, который их требует, определить, как их принимать. Эти стандартные определения могут складываться.
Terragrunt знает, что нужно пойти и изучить конфигурацию этих модулей, чтобы узнать, как получить доступ к их состоянию, что чрезвычайно полезно для использования зависимостей между несколькими рабочими пространствами / учетными записями AWS.
Terragrunt применяет зависимости в их подразумеваемом порядке.
В Terraform, поскольку состояние доступно только после запуска модуля, порядок запуска модулей имеет значение (а Terraform не знает этого порядка). Оператор должен задокументировать порядок применения вещей.
Terragrunt создает дерево зависимостей и запускает все команды в правильном порядке, чтобы все необходимые зависимости были доступны во время выполнения.
Terragrunt поощряет использование хороших методов программирования.
Глядя на проверенные модули в реестре модулей Terraform , вырисовывается закономерность: почти ни один из них не использует remote_state
источники данных. На самом деле организация Github terraform-aws-modules, на которой размещены десятки проверенных модулей, использует только одну remote_state
зависимость .
Это связано с тем, что использование remote_state
делает модули менее пригодными для повторного использования. В то время как переменные входные данные могут поступать откуда угодно, размещение remote_state
блоков в коде модуля ограничивает использование этого модуля, чтобы он работал только тогда, когда remote_state уже существует, и этот модуль имеет доступ к состоянию.
Бонус: Terragrunt упрощает тестирование.
Кроме того, зависимости Terragrunt имеют встроенную инъекцию зависимостей, что упрощает тестирование с помощью такого инструмента, как terratest .
Автоматическая генерация конфигурации Atlantis: избавляет от тяжелого труда
Чтобы поддерживать нашу инфраструктуру в актуальном состоянии, мы используем популярную систему CI/CD Atlantis . Иерархия зависимостей, созданная Terragrunt, позволяет нам автоматически генерировать нашу конфигурацию Atlantis, заменяя болезненный процесс ее ручной настройки. В Transcend мы с гордостью создали и поддерживаем инструмент с открытым исходным кодом terragrunt-atlantis-config : наш генератор конфигурации Atlantis.
Мы создали этот инструмент после борьбы с ручным и подверженным ошибкам процессом обновления нашего atlantis.yaml
файла. Эти файлы могут состоять из десятков тысяч строк, дерево зависимостей для каждого модуля должно быть определено в конфигурации, а неправильно определенные зависимости завершатся автоматически.
Избавьте себя от страданий: сгенерируйте свою конфигурацию.
Поддержка переменных среды: не рекомендуется использовать жестко закодированные значения.
Переменные среды позволяют, например, программно заполнять значения профиля AWS. Они могут обеспечить запасные варианты и препятствуют жесткому кодированию значений. Жизнь лучше с переменными окружения.
Terraform не планирует в ближайшее время поддерживать переменные окружения (как видно apparentlymart
из ответа пользователя (сопровождающего Terraform) на этот запрос на вытягивание ), и на то есть веские причины! Это может привести к очень трудным для отладки ошибкам Terraform, когда дочерние модули зависят от переменных среды, которые никогда не устанавливались явно. Философия Terraform заключается не в том, что переменные среды плохи, а в том, что они должны быть явно установлены и доступны только для модулей верхнего уровня. Поскольку Terragrunt — это оболочка, которая работает только с корневыми модулями, она может поддерживать и поддерживает переменные среды.
Generate
блоки: удалить повторяющуюся конфигурацию Terraform
Если вы используете AWS, сколько раз вы объявляли переменную для tags
? Как насчет переменной для региона AWS для развертывания? Как насчет роли IAM в провайдере? В скольких местах вы указали одни и те же ограничения версии поставщика Terraform?
Я так и думал. Вместо того, чтобы портировать этот общий код повсюду, с помощью Terragrunt можно использовать generate
блоки для динамического добавления кода Terraform в модули до того, как они будут запланированы или применены.
Написание провайдера со всеми необходимыми переменными позволяет вам добавить этот провайдер с помощью короткого generate
блока везде, где это необходимо.
Автоматическая пометка ресурсов: универсальное применение метаданных
Говоря о tags
повсеместном использовании переменных, сколько мест вы определяете, какие теги передавать модулям? Они добавляют ценные метаданные, которые можно использовать для отслеживания всего, от самых дорогих ресурсов до расположения исходного кода ресурса. Если бы вы хотели добавить новый тег к каждому отдельному ресурсу в вашей учетной записи AWS с именем файла Terraform, который его создал, сколько работы это потребовало бы?
С Terragrunt это просто. Используйте generate
блок, как описано выше, чтобы везде добавить tags
переменную с другими общими переменными, которые вы хотите, затем в вашем родительском файле Terragrunt (у нас есть по одному для каждой среды) добавьте ввод:
И точно так же каждый отдельный ресурс сообщает нам, какой модуль им управляет. Если я просматриваю консоль AWS и вижу, что какая-то служба ECS дает сбой из-за отсутствия переменной среды, я могу просто проверить TerraformPath
тег на этой службе, чтобы увидеть, какой именно файл в нашей кодовой базе мне нужно отредактировать.
Вывод произвольных команд из переменных: упрощает использование библиотеки
Функция Terragrunt run_cmd
выполняет произвольные команды в локальной оболочке. Это полезно в некоторых исключительных случаях, когда нет поставщика Terraform (библиотеки) для конкретной задачи.
Например, мы используем AWS IAM Authentication для подключения к нашим кластерам Hashicorp Vault. Внутри провайдера Vault мы можем пройти аутентификацию, используя метаданные экземпляра IAM… но для завершения аутентификации нам нужны заголовки запросов AWS IAM, а получение заголовков запросов AWS IAM — сложная задача. Путь наименьшего сопротивления — использование внешних библиотек aws4
, таких как популярная библиотека NodeJS.
К счастью, поскольку я могу установить переменные для произвольного вывода команды, чтобы передать эту сложную переменную в Terraform, мне просто нужно написать скрипт, который генерирует заголовки, а затем указать переменную на этот вывод, как я делаю iam_request_headers
в примере Terraform. код ниже:
Затем во входные данные Terragrunt просто добавьте:
Престо! Terragrunt открывает доступ к множеству других скриптов!
read_terragrunt_config
imports: Удалите повторяющийся код Terragrunt:
Terragrunt предлагает совершенно новую функцию read_terragrunt_config
, позволяющую импортировать код Terragrunt из внешних файлов Terragrunt.
В Transcend у нас есть несколько определений контейнеров ECS, которые используют общее подмножество переменных среды. В общем файле мы создаем карту этих общих переменных окружения, а затем в наших модулях-контейнерах мы просто читаем эту общую конфигурацию и объединяем ее результаты с нашими входными данными.
Хотя сбор наших переменных среды имеет некоторую сложность (у него довольно много зависимостей и вызовов функций), он read_terragrunt_config
позволяет нам изолировать эту сложность в одном месте и использовать ее результаты в других местах.
Terragrunt продолжает развиваться и совершенствоваться
Как и в случае с любым программным обеспечением, со временем мы заметили некоторые недостающие функции, и нам пришлось работать над некоторыми шероховатостями. Давайте взглянем на некоторые исторические проблемы, с которыми мы столкнулись, и как мы с ними справились:
- Управление задержкой.
- Обеспечение согласованности использования переменных файлов
- Уменьшение многословия вывода.
Управление задержкой
Как мы показали ранее, блоки конфигурации зависимостей Terragrunt невероятно мощны и полезны. Однако, поскольку модули часто имеют зависимости от десятков других модулей, каждый из которых может иметь свои собственные зависимости, дерево зависимостей может быстро раздуваться. Как только мы достигли около 300 модулей верхнего уровня, некоторые из которых имеют более 50 зависимостей, которые Terraform утверждает, Terragrunt должен искать, запуск terragrunt plan
команд может занять более десяти минут.
Чтобы справиться с этой задержкой, мы отправили запрос на извлечение (PR) в репозиторий Terragrunt , который обновил библиотеку для одновременного поиска всех зависимостей состояния с помощью горутин. Мы предложили PR в одну пятницу в 22:00, он был объединен менее чем за час, а на следующее утро он уже был выпущен на Homebrew.
После внесения этих изменений наш самый медленный модуль теперь занимает всего две минуты до plan
первого запуска и менее минуты до plan
установки кеша Terragrunt.
Обеспечение согласованности использования переменных файлов
Как в Terraform, так и в Terragrunt можно вносить изменения с предварительным созданием файла плана или без него. Либо:
Или просто,
Поскольку Terragrunt так много автоматизирует, становится важным убедиться, что конфигурация приложения защищает от причуд Terraform: в противном случае легко непреднамеренно передать переменные в apply
файл плана, и все взорвется . (На самом деле это будет только ошибка. Это просто похоже на взрыв.)
Передовой опыт Terragrunt, заключающийся в том, что он всегда запускается terragrunt plan
раньше всех terraform apply
, поможет решить эту проблему, но в Transcend мы решили пойти еще дальше, чтобы полностью устранить эту проблему.
Вместо использования файлов переменных Terraform мы загружаем все наши секретные значения непосредственно из кластеров Hashicorp Vault с помощью Hashicorp Vault Provider или через прямые запросы к нашему кластеру Vault из кода нашего приложения. Таким образом, мы никогда не делимся секретными файлами вручную (секреты в git не защищены), и мы можем быть очень уверены в безопасности нашего секретного хранилища.
Поскольку Terraform и Terragrunt хранят файлы состояния Terraform в виде открытого текста со всеми видимыми секретами , что является постоянной темой более шести лет обсуждения , перемещая как можно больше наших секретов в Vault, мы гарантируем, что они никогда не будут присутствовать в нашем состоянии.
Это не только делает наш инфраструктурный код компактным (что упростило перенос наших развертываний в систему CI с Atlantis), но и наши файлы состояния теперь намного более защищены в случае утечки: огромная победа в безопасности!
Уменьшение многословия вывода
Terragrunt — довольно многословный инструмент, настолько, что его самая популярная проблема за все время — это запрос на чистое ведение журнала. Мы можем относиться.
Некоторые из наших модулей создают тысячи журналов для stderr
каждого файла plan
. Эти журналы могут быть полезны при возникновении ошибок, но имеют тенденцию быть избыточными, когда планы выполняются.
Чтобы справиться с этим, мы написали собственную небольшую оболочку Terragrunt , которая при успешных запусках отображает только выходные данные плана Terraform. Когда возникают проблемы с нашим кодом Terraform, наша оболочка отображает весь набор журналов Terragrunt, чтобы мы могли легко отладить, что пошло не так.
Не стесняйтесь использовать и разветвлять наше решение в этой сути!
С большим преимуществом и минимальным недостатком Terragrunt по-прежнему остается победителем.
Каждый инструмент в стеке системы усложняет работу, увеличивая как когнитивную нагрузку при работе в системе, так и входной барьер для новых разработчиков. В общем, мы пытаемся избегать сложности ради сложности и стремимся по возможности создавать компактную кодовую базу.
Мы в Transcend обнаружили, что Terragrunt не только сокращает нашу кодовую базу на несколько тысяч строк, но и значительно упрощает код нашей инфраструктуры. Нам больше не нужно повторять конфигурацию нашего провайдера, состояния или зависимостей, поэтому логика нашего кода теперь сосредоточена исключительно на том, на чем она должна быть сосредоточена: на ресурсах терраформирования, которые нужны нашим разработчикам.
В тех редких случаях, когда Terragrunt не оправдал наших ожиданий, сопровождающие были чрезвычайно открыты для отзывов, запросов функций и запросов на вытягивание и быстро устраняли наши болевые точки.
Благодаря всем замечательным функциям, которые Terragrunt привносит в Terraform, мы можем быть уверены, что каждое развертывание нашей инфраструктуры будет создавать безопасные, поддающиеся аудиту системы, обеспечивающие надежную защиту конфиденциальных данных наших клиентов.