Подтвердить что ты не робот

Рекомендации по использованию Terraform

Я сейчас перехожу на нашу инфраструктуру в terraform. Какая наилучшая практика для фактического управления файлами террароформ и состояния? Я понимаю инфраструктуру как код, и я буду передавать свои .tf файлы в git, но могу ли я также выполнить tfstate? Должно ли это находиться где-то как S3? Я бы хотел, чтобы в конечном итоге CI справился со всем этим, но это далеко растянулось и требует, чтобы я выяснил движущиеся части для файлов.

Я действительно просто смотрю, как люди там действительно используют этот тип материала в производстве

4b9b3361

Ответ 1

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

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

файлы .tfstate

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

Это можно подтвердить, глядя на Terraform .gitignore.

Контроль разработчика

Наша цель - обеспечить больший контроль над инфраструктурой для разработчиков, одновременно поддерживая полный аудит (журнал git) и возможность проверять исправления изменений (запросы на извлечение). Имея это в виду новый рабочий процесс инфраструктуры, к которому я стремлюсь:

  1. Базовая основа общего AMI, который включает многоразовые модули, например, кукольный.
  2. Основная инфраструктура, предоставляемая DevOps с использованием Terraform.
  3. Разработчики изменяют конфигурацию Terraform в Git по мере необходимости (количество экземпляров; новый VPC; добавление региона/зоны доступности и т.д.).
  4. Конфигурация Git отправлена, и запрос на отправку отправлен на проверку работоспособности сотрудником DevOps.
  5. В случае одобрения вызывает webhook к CI для сборки и развертывания (пока не знаете, как разделить несколько сред)

Редактировать 1 - Обновить текущее состояние

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

раскладка

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

Модули

Следующим шагом было создание единого репозитория git для хранения наших модулей terraform. Наша структура каталогов верхнего уровня для модулей выглядит следующим образом:

tree -L 1 .

Результат:

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

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

клей

У нас есть второй репозиторий с нашим glue который использует модули, упомянутые выше. Он изложен в соответствии с нашим таксономическим документом:

.
├── README.md
├── clientA
│   ├── eu-west-1
│   │   └── dev
│   └── us-east-1
│       └── dev
├── clientB
│   ├── eu-west-1
│   │   ├── dev
│   │   ├── ec2-keys.tf
│   │   ├── prod
│   │   └── terraform.tfstate
│   ├── iam.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
    │   ├── aws.tf
    │   ├── dev
    │   ├── iam-roles.tf
    │   ├── ec2-keys.tf
    │   ├── prod
    │   ├── stg
    │   └── terraform.tfstate
    └── iam.tf

На уровне клиента у нас есть специфичные для учетной записи AWS файлы .tf которые предоставляют глобальные ресурсы (например, роли IAM); следующий - уровень региона с открытыми ключами EC2 SSH; Наконец, в нашей среде (dev, stg, prod т.д.) stg наши настройки VPC, соединения экземпляров, пиринговые соединения и т.д.

Примечание: как вы можете видеть, я иду против своего собственного совета по поводу сохранения terraform.tfstate в git. Это временная мера, пока я не перейду на S3, но меня устраивает, так как я сейчас единственный разработчик.

Следующие шаги

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

Редактировать 2 - Изменения

Прошел почти год с тех пор, как я написал этот первоначальный ответ, и состояние как Terraform, так и меня, значительно изменилось. Сейчас я нахожусь на новой должности, используя Terraform для управления кластером Azure, и Terraform теперь v0.10.7.

государственный

Люди неоднократно говорили мне, что государство не должно идти в Git - и они правы. Мы использовали это как временную меру с командой из двух человек, которая опиралась на коммуникацию и дисциплину разработчиков. Располагая более крупной распределенной командой, мы теперь полностью используем удаленное состояние в S3 с блокировкой, предоставляемой DynamoDB. В идеале это будет перенесено в консул, теперь это v1.0 для сквозных облачных провайдеров.

Модули

Ранее мы создавали и использовали внутренние модули. Это все еще так, но с появлением и ростом реестра Terraform мы стараемся использовать их как минимум.

Файловая структура

Новая позиция имеет гораздо более простую таксономию с двумя средами infx - dev и prod. Каждый из них имеет свои переменные и выходные данные, повторно используя наши модули, созданные выше. Поставщик remote_state также помогает в совместном использовании выводов созданных ресурсов между средами. Наш сценарий - это субдомены из разных групп ресурсов Azure в глобально управляемый TLD.

├── main.tf
├── dev
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

планирование

Опять же, с дополнительными проблемами распределенной команды, мы теперь всегда сохраняем наш результат команды terraform plan. Мы можем проверить и узнать, что будет выполнено без риска каких-либо изменений между plan и этапом apply (хотя блокировка помогает в этом). Не забудьте удалить этот файл плана, поскольку он может содержать "секретные" переменные в виде простого текста.

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

Ответ 2

Мы активно используем Terraform, и мы рекомендуем следующие настройки:

Расположение файла

Мы настоятельно рекомендуем хранить код Terraform для каждой из ваших сред (например, stage, prod, qa) в отдельных наборах шаблонов (и, следовательно, в отдельных файлах .tfstate). Это важно для того, чтобы ваши отдельные среды были фактически изолированы друг от друга при внесении изменений. В противном случае, пока возиться с некоторым кодом при постановке, слишком легко взорвать что-то в prod. Посмотрите Terraform, VPC, и почему вы хотите получить файл tfstate для каждого env, чтобы подробно обсудить почему.

Поэтому наш типичный формат файла выглядит следующим образом:

stage
  └ main.tf
  └ vars.tf
  └ outputs.tf
prod
  └ main.tf
  └ vars.tf
  └ outputs.tf
global
  └ main.tf
  └ vars.tf
  └ outputs.tf

Весь код Terraform для VPC этапа попадает в папку stage, весь код VPC продукта попадает в папку prod, а весь код, который находится за пределами VPC (например, пользователи IAM, темы SNS, сегменты S3), попадает в папку global папка.

Обратите внимание, что условно мы обычно разбиваем наш код Terraform на 3 файла:

  • vars.tf: входные переменные.
  • outputs.tf: выходные переменные.
  • main.tf: фактические ресурсы.

Модули

Как правило, мы определяем нашу инфраструктуру в двух папках:

  1. infrastructure-modules: эта папка содержит небольшие, многократно используемые версии модулей. Подумайте о каждом модуле как о том, как создать отдельный элемент инфраструктуры, такой как VPC или база данных.
  2. infrastructure-live: эта папка содержит действующую работающую инфраструктуру, которую она создает путем объединения модулей в infrastructure-modules. Думайте о коде в этой папке как о реальных домах, которые вы построили из своих чертежей.

Модуль Terraform - это любой набор шаблонов Terraform в папке. Например, у нас может быть папка vpc в infrastructure-modules которая определяет все таблицы маршрутов, подсети, шлюзы, ACL и т.д. Для одного VPC:

infrastructure-modules
  └ vpc
    └ main.tf
    └ vars.tf
    └ outputs.tf

Затем мы можем использовать этот модуль в infrastructure-live/stage и infrastructure-live/prod для создания VPC stage и prod. Например, вот как выглядит infrastructure-live/stage/main.tf:

module "stage_vpc" {
  source = "git::[email protected]:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"

  vpc_name         = "stage"
  aws_region       = "us-east-1"
  num_nat_gateways = 3
  cidr_block       = "10.2.0.0/18"
}

Чтобы использовать модуль, вы используете ресурс module и указываете его поле source либо на локальный путь на вашем жестком диске (например, source = "../infrastructure-modules/vpc"), либо, как в примере выше, на URL-адрес Git (см. источники модуля). Преимущество Git URL заключается в том, что мы можем указать определенный git sha1 или тег (ref=v0.0.4). Теперь мы не только определяем нашу инфраструктуру как группу небольших модулей, но также можем создавать версии этих модулей и при необходимости тщательно обновлять или выполнять откат.

Мы создали несколько повторно используемых, протестированных и задокументированных пакетов инфраструктуры для создания VPC, кластеров Docker, баз данных и т.д., И большинство из них - просто модули версии Terraform.

государственный

Когда вы используете Terraform для создания ресурсов (например, экземпляры EC2, базы данных, VPC), он записывает информацию о том, что он создал, в файл .tfstate. Чтобы внести изменения в эти ресурсы, каждому .tfstate вашей команды необходим доступ к этому .tfstate файлу .tfstate, но вы НЕ .tfstate проверять его в Git (объяснение почему см. Здесь).

Вместо этого мы рекомендуем хранить файлы .tfstate в S3, включив удаленное состояние Terraform, которое будет автоматически загружать/извлекать последние файлы каждый раз, когда вы запускаете Terraform. Убедитесь, что в вашей .tfstate управление версиями, чтобы вы могли откатиться к более .tfstate файлам .tfstate на случай, если вы каким-либо образом повредите последнюю версию. Однако, важное примечание: Terraform не обеспечивает блокировку. Поэтому, если два члена команды запускают terraform apply одновременно для одного и того же файла .tfstate, они могут перезаписать изменения друг друга.

Чтобы решить эту проблему, мы создали инструмент с открытым исходным кодом под названием Terragrunt, который является тонкой оболочкой для Terraform, которая использует Amazon DynamoDB для обеспечения блокировки (которая должна быть полностью бесплатной для большинства команд). Проверьте дополнительную автоматическую блокировку и настройку состояния в Terraform с помощью Terragrunt.

дальнейшее чтение

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

Обновление: всеобъемлющее руководство по серии постов в блоге Terraform стало настолько популярным, что мы превратили его в книгу под названием Terraform: Up & Running !

Ответ 3

Ранее remote config позволяла это, но теперь была заменена " бэкэндами ", так что удаленное использование Terraform больше не доступно.

terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote push

Смотрите документы для деталей.

Ответ 4

Более подробно рассмотрено @Евгением Брикманом, но специально отвечающим на вопросы ОП:

Как лучше всего управлять файлами и состоянием terraform?

Используйте git для файлов TF. Но не проверяйте файлы состояния в (т.е. tfstate). Вместо этого используйте Terragrunt для синхронизации/блокировки файлов состояния на S3.

но я также передаю tfstate?

Нет.

Должен ли он находиться где-то вроде S3?

да

Ответ 5

Я знаю, что здесь много ответов, но мой подход совсем другой.

⁃   Modules
⁃   Environment management 
⁃   Separation of duties

Модули

  1. Создание модулей для логических наборов ресурсов. Пример: если ваша цель - развернуть API, для которого требуются БД, виртуальные машины высокой доступности, автоматическое масштабирование, DNS, PubSub и хранилище объектов, тогда все эти ресурсы должны быть настроены в одном модуле.
  2. Избегайте создания модулей, которые используют один ресурс. Это можно и было сделано, и многие модули в реестре делают это, но это практика, которая помогает с доступностью ресурсов, а не с оркестровкой инфраструктуры. Пример: модуль для AWS EC2 помогает пользователю получить доступ к EC2, делая более простыми вызовы сложных конфигураций, но модуль, подобный примеру в 1., помогает пользователю при организации инфраструктуры приложений, компонентов или сервисов.
    1. Избегайте объявлений ресурсов в вашем рабочем пространстве. Это больше о поддержании вашего кода в чистоте и порядке. Поскольку модули легко версии, у вас есть больше контроля над своими выпусками.

Управление окружающей средой

IaC сделал процесс SDLC релевантным для управления инфраструктурой, и это ненормально ожидать наличия инфраструктуры разработки, а также сред разработки приложений.

  1. Не используйте папки для управления средами IaC. Это приводит к дрейфу, поскольку нет единого шаблона для вашей инфраструктуры.
  2. Используйте одно рабочее пространство и переменные для управления спецификациями среды. Пример: напишите свои модули так, чтобы при изменении переменной среды (популярный var.stage) план изменялся в соответствии с вашими требованиями. Как правило, среда должна меняться как можно меньше, а количество, экспозиция и мощность обычно являются переменными конфигурациями. Dev может развернуть 1 ВМ с 1 ядром и 1 ГБ ОЗУ в частной топологии, но может использоваться 3 ВМ с 2 ядрами и 4 ГБ ОЗУ с дополнительной общедоступной топологией. Конечно, у вас может быть больше вариантов: dev может запустить процесс базы данных на том же сервере, что и приложение, чтобы сэкономить на затратах, но у производства может быть выделенный экземпляр БД. Всем этим можно управлять, изменяя одну переменную, троичные операторы и интерполяцию.

Разделение обязанностей

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

  1. Разбейте свою инфраструктуру по обязанностям, обязанностям или командам. Пример: центральный ИТ-контроль, лежащий в основе общих общих служб (виртуальные сети, подсети, общедоступные IP-адреса, группы журналов, ресурсы управления, многопользовательские БД, общие ключи и т.д.), В то время как команда API контролирует только ресурсы, необходимые для их обслуживания (ВМ, LB), PubSub и т.д.) И используют центральные ИТ-сервисы посредством поиска источников данных и удаленного состояния.
    1. Управление доступом команды. Пример: центральный ИТ может иметь права администратора, но команда API имеет доступ только к ограниченному набору API публичного облака.

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

Эта стратегия проводит параллели с мультисчетной стратегией AWS. Прочитайте для получения дополнительной информации.

CI/CD -

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

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

Ответ 6

Прежде чем ответы будут очень убедительными и информативными, я постараюсь добавить свои 2 цента здесь

Общие рекомендации по структурированию кода

  1. Работать с меньшим количеством ресурсов проще и быстрее:

    • Применяются terraform plan terraform Cmds и terraform которые делают облачные вызовы API для проверки состояния ресурсов.
    • Если у вас вся инфраструктура в одной композиции, это может занять много минут (даже если у вас есть несколько файлов в одной папке).
  2. Радиус взрыва меньше с меньшими ресурсами:

    • Изоляция несвязанных ресурсов друг от друга путем размещения их в отдельных композициях (папках) снижает риск, если что-то пойдет не так.
  3. Начните свой проект, используя удаленное состояние:

    • Ваш ноутбук не место для вашей инфраструктуры, источник правды.
    • Управление файлом tfstate в git - это кошмар.
    • Позже, когда уровни инфраструктуры начинают расти в любом направлении (количество зависимостей или ресурсов).
    • пример модуля: https://github.com/cloudposse/terraform-aws-tfstate-backend
    • Ссылка на инструмент: https://github.com/camptocamp/terraboard
  4. Попробуйте применить согласованную структуру и соглашение об именах:

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

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

  7. Используйте источники data и terraform_remote_state специально как связующее звено между модулями инфраструктуры внутри композиции.

(ссылка на статью: https://www.terraform-best-practices.com/code-structure)


Пример:

Работать с меньшим количеством ресурсов проще и быстрее, поэтому ниже мы представляем рекомендуемый макет кода.

ПРИМЕЧАНИЕ: так же, как ссылка, которой не следует строго следовать, поскольку каждый проект имеет свои специфические характеристики

.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate 
│   ├── main.tf
│   ├── ...
├── 2_secrets
│   ├── main.tf
│   ├── ...
├── 3_identities
│   ├── account.tf
│   ├── roles.tf
│   ├── group.tf
│   ├── users.tf
│   ├── ...
├── 4_security
│   ├── awscloudtrail.tf
│   ├── awsconfig.tf
│   ├── awsinspector.tf
│   ├── awsguarduty.tf
│   ├── awswaf.tf
│   └── ...
├── 5_network
│   ├── account.tf
│   ├── dns_remote_zone_auth.tf
│   ├── dns.tf
│   ├── network.tf
│   ├── network_vpc_peering_dev.tf
│   ├── ...
├── 6_notifications
│   ├── ...
├── 7_containers
│   ├── account.tf
│   ├── container_registry.tf
│   ├── ...
├── config
│   ├── backend.config
│   └── main.config
└── readme.md

Ответ 7

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

Как Евгений Брикман упомянул его лучше иметь структуру модулей.