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

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

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

5 ответов


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

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

.tfstate файлы

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

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

для разработчиков-контроль

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

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

Edit 1-обновление текущего состояния

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

планировка

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

модули

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

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 etc) наши установки VPC, творение экземпляра и соединения etc. хранятся.

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

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

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

Изменить 2 - Изменения

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

государство

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

модули

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

структура файла

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

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

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

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

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


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

мы настоятельно рекомендуем хранить код Terraform для каждой из ваших сред (например, stage, prod, qa) в отдельных наборах шаблонов (и, следовательно, отдельно .tfstate файлы). Это важно для того, чтобы ваши отдельные среды были фактически изолированы друг от друга при внесении изменений. В противном случае, возясь с каким-то кодом в постановке, слишком легко взорвать что-то прод тоже. См.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 папка, весь код для prod VPC переходит в prod папка, и весь код, который живет за пределами VPC (например, пользователи IAM, темы SNS, ведра S3), входит в global папка.

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

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

модули

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

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

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

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

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

module "stage_vpc" {
  source = "git::git@github.com: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 (см. модуль источники). Преимущество URL git заключается в том, что мы можем указать конкретный git sha1 или тег (ref=v0.0.4). Теперь мы не только определяем нашу инфраструктуру как набор небольших модулей, но и можем модифицировать эти модули и тщательно обновлять или откатывать их по мере необходимости.

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

государство

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

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

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

более дальнеишее чтение

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

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


С remote config, теперь это стало намного проще:

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

посмотреть docs для сведения.


более подробно освещено @Yevgeny Brikman, но конкретно отвечает на вопросы OP:

What's the best practice for actually managing the terraform files and state?

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

but do I commit tfstate as well? 

нет.

Should that reside somewhere like S3?

да


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

⁃   Modules
⁃   Environment management 
⁃   Separation of duties

модули

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

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

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

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

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

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

  1. Разбейте свою инфраструктуру по обязанностям, обязанностям или командам. Пример: централизованный ИТ-контроль базовых общих служб(виртуальных сетей, подсетей, общедоступных IP-адресов, групп журналов, ресурсов управления, нескольких арендованных DBs, общих ключей и т.д.) в то время как команда API контролирует только ресурсы, необходимые для их службы (VMs, LBs, PubSub и т. д.), и потребляет центральные свои службы Через Источник данных и удаленное состояние поиски.
    1. управление доступом команды. Пример: Central он может иметь права администратора, но команда API имеет доступ только к ограниченному набору общедоступных облачных API.

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

эта стратегия проводит параллели со стратегией нескольких аккаунтов AWS. Have a read for more информация.

CI / CD

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

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