Рекомендации по использованию Terraform [закрыто]

112

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

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

Марк Янг
источник

Ответы:

85

Я также нахожусь в состоянии переноса существующей инфраструктуры 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, каждая из которых имеет несколько подсетей. Ключом к легкому управлению этим было определение гибкой таксономии, охватывающей регион, среду, службу и владельца, которую мы можем использовать для организации нашего кода инфраструктуры (как терраформ, так и марионетки).

Модули

Следующим шагом было создание единого репозитория 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

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

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

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

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

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

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

государство

Люди неоднократно говорили мне, что состояние не должно входить в Git - и они правы. Мы использовали это в качестве временной меры с командой из двух человек, которая полагалась на общение с разработчиками и дисциплину. Благодаря более крупной распределенной команде мы теперь полностью используем удаленное состояние в S3 с блокировкой, обеспечиваемой DynamoDB. В идеале это будет перенесено на consul, теперь это 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 и продолжаем учиться и совершенствоваться с добавлением новых функций.

Ewan
источник
Были ли у вас какие-то проблемы / проблемы после этого ответа? Кажется, твое очень похоже на то, что я собираюсь сделать, но ты можешь быть дальше меня.
Марк Янг
3
Мне любопытно, почему вы думаете, что файлы tfstate не должны храниться в git? Просто потому, что старое состояние не стоит сохранять, или есть другие проблемы?
agbodike 03
3
@agbodike - при работе в качестве одного разработчика или части очень небольшой команды tfstate может храниться в git до тех пор, пока он регулярно фиксируется и отправляется, чтобы избежать конфликтов. Мой следующий шаг - настроить это в соответствии с их документами об удаленном состоянии в S3 (в которых также говорится: «это усложняет работу с Terraform в команде, поскольку это частый источник конфликтов слияния. Удаленное состояние помогает решить эти проблемы»). . Как и в большинстве случаев, хорошее командное общение может помочь решить большинство / все проблемы, независимо от тактики удержания состояния :-)
Ewan
1
@ the0ther - Боюсь, что мой основной репозиторий является проприетарным, однако в настоящее время я работаю над личным репозиторием, который в ближайшем будущем сделаю общедоступным.
Ewan
2
Есть ли удача с репозиторием Git @Ewan? Я бы хотел посмотреть, что ты делаешь.
Дэвид
85

Мы активно используем 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папку, весь код для VPC prod помещается в 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 в папке. Например, у нас может быть папка с именем vpcin, infrastructure-modulesкоторая определяет все таблицы маршрутов, подсети, шлюзы, ACL и т. Д. Для одного VPC:

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

Затем мы можем использовать этот модуль в infrastructure-live/stageи infrastructure-live/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 или tag ( ref=v0.0.4). Теперь мы не только определяем нашу инфраструктуру как набор небольших модулей, но и можем изменять версии этих модулей и тщательно обновлять или откатывать по мере необходимости.

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

государство

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

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

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

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

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

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

Евгений Брикман
источник
Думаю, это правильный ответ. Используйте модули, изменяйте их версии и разделяйте среды.
wrangler
Нужно ли перезапускать шаг удаленной настройки каждый раз, когда вы хотите работать с другим компонентом / средой / модулем / другим терраформом, если не используете terragrunt или другую оболочку?
jmreicha
@jmreicha: вам нужно запустить, remote configесли вы только что проверили свои конфигурации Terraform или если вы хотите изменить предыдущую удаленную конфигурацию. Terraform 0.9 представит концепцию backends, которая во многом упростит это. См. Этот PR для более подробной информации.
Евгений Брикман
Просто чтобы я понял - я работаю над окружением «stage», а потом начинаю работать над «prod». Мне нужно будет повторно запустить remote configкоманду, чтобы указать на состояние prod. Предполагая различное состояние для каждой среды. Это правильно? С нетерпением жду v0.9.
jmreicha
Если вы собирались развернуть один и тот же набор .tfфайлов в двух разных средах, да, вам нужно будет запускать remote configкаждый раз при переключении. Очевидно, что это очень подвержено ошибкам, поэтому я не рекомендую использовать эту технику. Вместо этого ознакомьтесь с рекомендуемым макетом файла Terraform в этом сообщении в блоге, а также с тем, как использовать модули Terraform в этом сообщении в блоге .
Евгений Брикман
9

Раньше remote configэто разрешалось, но теперь было заменено на " backends ", поэтому удаленный терраформ больше не доступен.

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

Подробности см. В документации .

Шантану
источник
Нужно ли перенастраивать удаленный источник каждый раз, когда вы хотите работать с другим компонентом / средой / модулем terraform / чем-то еще?
jmreicha
6

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

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

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

но могу ли я также передать tfstate?

Нет.

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

да

Snowcrash
источник
2

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

   Modules
   Environment management 
   Separation of duties

Модули

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

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

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

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

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

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

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

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

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

CI / CD-

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

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

Генри Добсон
источник
0

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

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

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

    • Cmds terraform planи terraformapply выполняют вызовы облачного 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
Экзекьель Барриреро
источник
0

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

  1. Не пишите один и тот же код снова (возможность повторного использования)
  2. Храните конфигурацию среды отдельно, чтобы ее было легко поддерживать.
  3. Используйте удаленный серверный модуль s3 (зашифрованный) и динамо-базу данных для обработки блокировки параллелизма
  4. Создайте модуль и используйте этот модуль в основной инфраструктуре несколько раз, как функцию многократного использования, которую можно вызывать несколько раз, передавая другой параметр.

Обработка нескольких сред

В большинстве случаев рекомендуемый способ - использовать terraform «рабочее пространство» для обработки нескольких сред, но я считаю, что использование рабочего пространства может варьироваться в зависимости от способа работы в организации. Другой - это сохранение кода Terraform для каждой из ваших сред (например, stage, prod, QA) для разделения состояний среды. Однако в этом случае мы просто копируем один и тот же код во многих местах.

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

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

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

Конфигурация, относящаяся к средам

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

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

Условный пропуск инфраструктурной части

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

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

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

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

Для справки: https://github.com/mattyait/devops_terraform

Махаттам
источник
0

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

Лучший подход - иметь один стек для всех сред (скажем, dev, preprod и prod). Для работы в единой среде используйте terraform workspace.

terraform workspace new dev

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

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

Таким образом вы получите ведра под названием

  • мой-tf-test-bucket-dev
  • мой-TF-тест-ведро-препрод
  • мой-tf-test-bucket-prod

после применения к указанным выше рабочим областям (используйте terraform workspace select <WORKSPACE>для изменения среды). Чтобы сделать код даже мультирегиональным, сделайте это так:

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

получить (для региона us-east-1)

  • мой-tf-test-bucket-us-east-1-dev
  • мой-TF-тест-ведро-нас-восток-1-препрод
  • мой-tf-test-bucket-us-east-1-prod
Магистр Хальдериан
источник
0

Некоторые рекомендации по использованию Terraform:

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

    account_number = «123456789012» account_alias = «mycompany»

  2. Запуск Terraform из контейнера докеров: Terraform выпускает официальный контейнер Docker, который позволяет вам легко контролировать, какую версию вы можете запустить.

При настройке задания сборки в конвейере CI / CD рекомендуется запускать контейнер Terraform Docker.

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

Чтобы узнать больше, обратитесь к моему блогу: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3

ND1772
источник
0

Я хотел бы внести свой вклад в эту тему.

  • Скорее всего, это будет AWS S3 + DynamoDB, если вы не используете Terraform Cloud.
  • Раздельная инфраструктура (сеть + RBAC) производственной и непроизводственной серверной части.
  • Запланируйте запретить доступ к файлам состояния (сетевой доступ и RBAC) извне указанной сети (например, пула агентов развертывания).
  • Не оставляйте серверную инфраструктуру Terraform вместе со средой выполнения. Используйте отдельную учетную запись.
  • Включите управление версиями объектов на ваших серверах Terraform, чтобы избежать потери изменений и файлов состояния, а также для сохранения истории состояний Terraform.

В некоторых особых случаях потребуется ручной доступ к файлам состояния Terraform. Такие вещи, как рефакторинг, критические изменения или исправление дефектов, потребуют выполнения операционным персоналом операций состояния Terraform. Для таких случаев запланируйте внеочередной контролируемый доступ к состоянию Terraform с помощью хоста-бастиона, VPN и т. Д.

Загляните в более длинный блог о лучших практиках, в котором это подробно рассматривается, включая рекомендации для конвейеров CI / CD.

Петр Гвязда
источник
-1

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

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

Rajendra
источник
-1

Используйте облако terraform для управления и сохранения состояний вместе с советами выше.

Ден Залман
источник