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


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

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

5 55

5 ответов:

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

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

.tfstate files

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

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

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

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

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

изменить 1-обновить текущее состояние

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

планировка

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

модули

следующим шагом было создание единого репозитория git для хранения нашей терраформы модули. Наша структура верхнего уровня 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 specific .tf файлы, которые предоставляют Глобальные ресурсы (например, роли IAM); далее идет уровень региона с открытыми ключами EC2 SSH; наконец, в нашей среде (dev,stg,prod и т. д.) наши ВКК установок, создание экземпляра и пиринговые соединения и т. д. хранятся.

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

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

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

Edit 2-Changes

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

State

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

модули

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

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

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

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

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

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

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

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

мы настоятельно рекомендуем хранить код Terraform для каждой из ваших сред (например, stage, prod, qa) в отдельных наборах шаблонов (и, следовательно, отдельно .tfstate файлы). Это важно для того, чтобы ваши отдельные среды были фактически изолированы друг от друга при внесении изменений. В противном случае, когда вы возитесь с каким-то кодом в staging, его слишком легко взорвать что-то в прод тоже. Смотрите 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 который определяет все таблицы маршрутов, подсети, шлюзы, ACL и т. д. Для одного 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") или, как в примере выше, git URL (см. модуль источники). Преимущество git URL заключается в том, что мы можем указать конкретный git sha1 или тег (ref=v0.0.4). Теперь мы не только определяем нашу инфраструктуру как набор небольших модулей, но и можем верифицировать эти модули и тщательно обновлять или откатывать их по мере необходимости.

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

State

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

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

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

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

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

Update: Полное руководство по Terraform blog post series стало настолько популярным, что мы расширили его в книгу под названием Терраформировать: Работает!

С 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 для сведения.

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

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. используйте одну рабочую область и переменные для управления спецификациями среды. Пример: писать свои модули так, чтобы при изменении переменной среды (ВАР.этап популярен) план изменяется в соответствии с вашими требованиями. Как правило, окружающая среда должна изменяться как можно меньше с количеством, экспозицией и емкостью, обычно являющимися переменными конфигурациями. Dev может развернуть 1 виртуальную машину с 1 ядром и 1 ГБ оперативной памяти в частной топологии, но производство может будьте 3 виртуальными машинами с 2 ядрами и 4 ГБ оперативной памяти с дополнительной публичной топологией. Конечно, у вас может быть больше вариантов: dev может запускать процесс базы данных на том же сервере, что и приложение, чтобы сэкономить затраты, но производство может иметь выделенный экземпляр БД. Все это можно управлять путем изменения одной переменной, тернарных операторов и интерполяции.

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

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

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

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

эта стратегия проводит параллели со стратегией мультисчета AWS. Есть читать для большего информация.

CI / CD

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

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