Лучшие практики при использовании Terraform

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

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

6 ответов

Решение

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

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

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

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

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

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

Мы активно используем 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. Например, вот что 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 (см. источники модуля). Преимущество Git URL заключается в том, что мы можем указать определенный git sha1 или тег (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!

С 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

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

Более детально рассмотрен @Eevgeny Brikman, но специально отвечающий на вопросы ОП:

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, для которого требуются БД, виртуальные машины высокой доступности, автоматическое масштабирование, 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, где обычно проверяют и проверяют шаблоны.

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

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

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

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

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

Я считаю, что при использовании 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

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

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

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

    • Cmdsterraform plan а также 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

Некоторые рекомендации по использованию 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

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

Лучший подход - иметь один стек для всех сред (скажем, 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

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

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

Как Yevgeniy Brikman, лучше иметь структуру модулей.

Другие вопросы по тегам