Лучшие практики Terraform для лучшего управления инфраструктурой

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

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

Давайте рассмотрим несколько лучших практик, которые помогут вам продвинуть свои навыки работы с Terraform на новый уровень. Если вы совсем новичок в Terraform, загляните в блог Terraform Spacelift Blog, где вы найдете множество материалов, учебников и примеров, которые помогут вам подтянуть свои навыки.

Содержание
  1. Ключевые понятия Terraform
  2. Язык конфигурации Terraform
  3. Ресурсы
  4. Источники данных
  5. Модули
  6. Состояние
  7. Провайдеры
  8. Лучшие практики IaC
  9. 1. Используйте контроль версий и предотвращайте внесение изменений вручную
  10. 2. Сдвиньте свою культуру в сторону совместного IaC
  11. Как структурировать проекты Terraform
  12. Лучшие практики, специфичные для Terraform
  13. 1. Удаленное состояние
  14. 2. Используйте существующие общие модули и модули сообщества
  15. 3. Импорт существующей инфраструктуры
  16. 4. Избегайте жесткого кодирования переменных
  17. 5. Всегда форматируйте и проверяйте
  18. 6. Используйте последовательное соглашение об именовании
  19. 7. Помечайте свои ресурсы
  20. 8. Внедрение политики как кода
  21. 9. Внедрите стратегию управления секретами
  22. 10. Тестируйте свой код Terraform
  23. 11. Включите отладку/поиск неисправностей
  24. 12. Используйте инструменты-помощники, чтобы облегчить себе жизнь
  25. Ключевые точки

Ключевые понятия Terraform

В этом разделе мы кратко опишем некоторые ключевые концепции Terraform. Если вы уже знакомы с ними, можете пропустить этот раздел.

Язык конфигурации Terraform

Terraform использует свой собственный язык конфигурации для объявления объектов инфраструктуры и их ассоциаций. Цель этого языка — быть декларативным и описывать состояние системы, которого мы хотим достичь.

Ресурсы

Ресурсы представляют объекты инфраструктуры и являются одним из основных блоков языка Terraform.

Источники данных

Источники данных обеспечивают наши конфигурации Terraform внешними данными или данными, определенными отдельными проектами Terraform.

Модули

Модули помогают нам группировать несколько ресурсов и являются основным способом упаковки ресурсов в Terraform для целей повторного использования.

Состояние

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

Провайдеры

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

Лучшие практики IaC

Прежде чем перейти к Terraform, давайте сначала проверим некоторые фундаментальные лучшие практики, которые применимы ко всем проектам Infrastructure as Code. Они должны использоваться в ваших процессах независимо от того, какой инструмент вы используете для управления облачной инфраструктурой.

1. Используйте контроль версий и предотвращайте внесение изменений вручную

Это кажется очевидным утверждением в 2022 году, но оно является основой всего остального. Мы должны относиться к конфигурациям нашей инфраструктуры как к коду приложения и применять те же лучшие практики для управления, тестирования, проверки и внедрения в производство. Мы должны использовать подход GitOps, который соответствует нашему сценарию использования, и внедрить автоматизированный рабочий процесс CI/CD для внесения изменений.

2. Сдвиньте свою культуру в сторону совместного IaC

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

Как структурировать проекты Terraform

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

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

Если мы имеем дело с небольшим проектом с ограниченным количеством инфраструктурных компонентов, то неплохой идеей будет максимально упростить конфигурацию Terraform. В таких случаях мы можем настроить только необходимые файлы для нашего корневого модуля, которые являются конфигурационными файлами, существующими в корневом каталоге. Небольшой проект может содержать только эти файлы main.tf, variables.tf, README.md. Некоторые другие файлы, которые вы можете найти удобными для использования, это outputs.tf для определения выходных значений вашего проекта, versions.tf для сбора всех прикрепленных версий для конфигураций, и providers.tf для настройки опций, связанных с используемыми вами провайдерами, особенно если их несколько.

Наша основная точка входа — main.tf, и в простых случаях мы можем добавить туда все наши ресурсы. Мы определяем наши переменные в variables.tf и присваиваем им значения в terraform.tfvars. Для объявления выходных значений мы используем файл outputs.tf. Подобный пример структуры проекта вы можете найти здесь.

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

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

Общепринятой практикой является разделение модулей в соответствии с правами собственности и ответственности, скоростью изменений и простотой управления. Для каждого модуля необходимо определить его входы и выходы и тщательно их документировать, чтобы потребители могли эффективно их использовать. Затем мы можем использовать выходы и terraform_remote_state для ссылки на значения в разных модулях или даже в разных состояниях Terraform. Следует помнить, что использование источника данных terraform_remote_state подразумевает доступ ко всему снимку состояния, а это может вызвать проблемы с безопасностью. Другим вариантом обмена параметрами между различными состояниями является использование внешнего инструмента для публикации и потребления данных, например Amazon SSM Parameter Store или HashiCorp Consul.

Нам нужно принять следующее решение: хранить весь код Terraform в одном репозитории (monorepo) или разделить наши конфигурации Terraform в нескольких репозиториях кода. Это считается большой дискуссией, поскольку оба подхода имеют недостатки и преимущества. В отрасли существует тенденция избегать гигантских монорепо и использовать отдельные конфигурации для более быстрой разработки модулей и гибкости. Лично я тоже предпочитаю именно такой подход.

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

Одним из вариантов является использование отдельного каталога для каждой среды и сохранение отдельного состояния для каждого каталога. Другим вариантом может быть хранение всех конфигураций Terraform в одном каталоге и передача различных переменных окружения для каждого окружения для соответствующей параметризации конфигурации. Ознакомьтесь с докладами Evolving Your Infrastructure with Terraform и How I Manage More Environments with Less Code in Terraform, чтобы получить вдохновение для структурирования ваших проектов.

Здесь вы можете найти пример структуры для трех различных окружений в каждом каталоге: production, staging и test. Каждая среда имеет собственное состояние и управляется отдельно от других, используя при этом общие или разделяемые модули. Хотя этот подход сопровождается некоторым дублированием кода, мы получаем улучшенную ясность, изоляцию среды и масштабируемость.

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

Лучшие практики, специфичные для Terraform

Итак, в предыдущих разделах мы говорили о некоторых общих лучших практиках IaC. Мы рассмотрели некоторые варианты оптимизации кода Terraform в соответствии с нашей организационной структурой и потребностями.

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

Цель состоит в том, чтобы дать вам подсказки и руководство по экспериментированию, исследованию и внедрению практик, которые имеют смысл для вашего случая использования.

1. Удаленное состояние

Вполне нормально использовать локальное состояние при проведении экспериментов, но для всего, что выше этой точки, используйте удаленное общее расположение состояния. Наличие единого удаленного бэкенда для вашего состояния считается одной из первых лучших практик, которые следует внедрять при работе в команде. Выберите тот, который поддерживает блокировку состояния, чтобы избежать одновременного изменения состояния несколькими людьми. Рассматривайте состояние как неизменяемое и избегайте ручного изменения состояния любой ценой. Убедитесь, что у вас есть резервные копии состояния, которые вы можете использовать в случае аварии. Для некоторых бэкендов, например AWS S3, можно включить версионность, чтобы быстро и легко восстановить состояние.

2. Используйте существующие общие модули и модули сообщества

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

3. Импорт существующей инфраструктуры

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

4. Избегайте жесткого кодирования переменных

Может возникнуть соблазн жестко закодировать некоторые значения, но постарайтесь по возможности избегать этого. Подумайте, не имеет ли смысл определить значение, которое вы присваиваете напрямую, как переменную, чтобы облегчить изменения в будущем. Более того, проверьте, можно ли получить значение атрибута через источник данных вместо того, чтобы задавать его явно. Например, вместо того чтобы найти идентификатор учетной записи AWS в консоли и задать его в terraform.tfvars как

aws_account_id=”99999999999”
Войти в полноэкранный режим Выйти из полноэкранного режима

Мы можем получить его из источника данных.

data "aws_caller_identity" "current" {}

locals {
    account_id    = data.aws_caller_identity.current.account_id
}
Войти в полноэкранный режим Выйти из полноэкранного режима

5. Всегда форматируйте и проверяйте

В IaC последовательность является важным долговременным фактором, и Terraform предоставляет нам некоторые инструменты, которые помогут нам в этом стремлении. Не забывайте запускать terraform fmt и terraform validate, чтобы правильно отформатировать ваш код и выявить любые проблемы, которые вы пропустили. В идеале, это должно быть сделано автоматически с помощью CI/CD конвейера или крючков предварительной коммисии.

6. Используйте последовательное соглашение об именовании

В Интернете можно найти множество предложений по использованию соглашений об именовании для кода Terraform. Самое главное — это не сами правила, а найти соглашение, с которым вашей команде удобно работать, и коллективно стараться соответствовать ему. Если вам нужны какие-то рекомендации, вот список правил, которым легко следовать:

  • Используйте подчеркивание (_) в качестве разделителя и строчные буквы в названиях.
  • Старайтесь не повторять тип ресурса в имени ресурса.
  • Для переменных с одним значением и атрибутов используйте существительные в единственном числе. Для списков или карт используйте существительные во множественном числе, чтобы показать, что они представляют несколько значений.
  • Всегда используйте описательные имена для переменных и выходов и не забывайте включать описание.

7. Помечайте свои ресурсы

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

Теги в аргументах Terraform должны быть объявлены в качестве последнего аргумента (только аргументы depends_on или lifecycle должны быть определены после тегов, если они уместны). Удобным вариантом, который поможет вам с тегами, является определение некоторых тегов по умолчанию (default_tags), которые применяются ко всем ресурсам, управляемым провайдером. Посмотрите этот пример, чтобы увидеть, как установить и переопределить теги по умолчанию для провайдера AWS. Если используемый вами провайдер не поддерживает теги по умолчанию, вы должны вручную передать эти теги в ваши модули и применить их к вашим ресурсам.

8. Внедрение политики как кода

По мере того как наши команды и инфраструктура расширяются, доверие к отдельным пользователям обычно снижается. Мы должны установить некоторые политики, чтобы обеспечить работоспособность и безопасность наших систем. Внедрение процесса Policy as Code позволяет нам определить правила того, что считается безопасным и приемлемым в масштабе, и автоматически проверять эти правила. В Spacelift для этого используется механизм с открытым исходным кодом Open Policy Agent (OPA).

9. Внедрите стратегию управления секретами

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

Как вы, вероятно, уже слышали, никогда не храните секреты в открытом виде и не фиксируйте их в системе контроля версий. Одна из техник, которую вы можете использовать — это передача секретов путем установки переменных окружения с помощью TF_VAR и пометки чувствительных переменных с помощью sensitive = true.

Более зрелым решением будет создание хранилища секретов, например, Hashicorp Vault или AWS Secrets Manager, которые будут обрабатывать доступ к секретам за вас. Таким образом, вы сможете защитить свои секреты в состоянии покоя и обеспечить шифрование без особых проблем. Вы также можете выбрать более продвинутые функции, такие как ротация секретов и журналы аудита. Имейте в виду, что такой подход обычно сопровождается стоимостью использования этой управляемой услуги.

10. Тестируйте свой код Terraform

Как и любой другой код, код IaC должен быть протестирован должным образом. Здесь существуют различные подходы, и опять же, вы должны найти тот, который имеет смысл для вас. Запуск terraform plan — самый простой способ быстро проверить, будут ли ваши изменения работать так, как ожидается. Далее, вы можете выполнить некоторый статический анализ для кода Terraform без необходимости его применения. Юнит-тестирование также является одним из вариантов проверки нормальной работы отдельных частей вашей системы.

Еще одним шагом может стать интеграция линкера Terraform в ваши CI/CD конвейеры и попытка отловить все возможные ошибки, связанные с облачными провайдерами, устаревшим синтаксисом, внедрением лучших практик и т. д. На шаг вперед вы можете настроить несколько интеграционных тестов, создав копию среды песочницы, применив там свой план, проверив, что все работает так, как ожидалось, собрав результаты, уничтожив песочницу и перейдя к применению в продакшене.

Существует множество инструментов, которые могут помочь вам в тестировании кода Terraform. Я перечислю некоторые из них в разделе «Инструменты-помощники» ниже.

11. Включите отладку/поиск неисправностей

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

TF_LOG=DEBUG <terraform command>
Вход в полноэкранный режим Выход из полноэкранного режима

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

12. Используйте инструменты-помощники, чтобы облегчить себе жизнь

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

  • tflint — Terraform linter для ошибок, которые план не может отловить.
  • tfenv — менеджер версий Terraform
  • checkov — Инструмент статического анализа Terraform
  • terratest — Библиотека Go, которая помогает вам в создании автоматизированных тестов для Terraform.
  • pre-commit-terraform — крючки git для автоматизации предварительной коммисии
  • terraform-docs — Быстрая генерация документации из модулей
  • spacelift — Платформа совместной доставки инфраструктуры
  • atlantis — Рабочий процесс для совместной работы над проектами Terraform
  • terraform-cost-estimation — Бесплатная служба оценки стоимости для ваших планов.Ознакомьтесь также с этим списком, в котором собрано множество других замечательных инструментов Terraform.

Ключевые точки

Мы изучили множество различных лучших практик для Terraform и Infrastructure as Code, проанализировали различные варианты обработки и структурирования наших проектов Terraform и увидели, как использование вспомогательных инструментов может облегчить нашу жизнь.

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

Спасибо за чтение, и я надеюсь, что эта статья «Лучшие практики Terraform» понравилась вам так же, как и мне.

Оцените статью
Procodings.ru
Добавить комментарий