Руководство по навигатору: настройка модульной инфраструктуры

[.Примечание]##

Note: это ранняя версия содержания книги Navigator’s Guide, предложения инженеров DigitalOcean Solutions. Цель книги - помочь бизнес-клиентам спланировать свои потребности в инфраструктуре, привести рабочие примеры и включить технический нюанс и «почему», который делает некоторые решения лучше других.

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

В предыдущем разделе использовались Terraform и Ansible для предоставления ресурсов (дроплетов, балансировщиков нагрузки и плавающих IP-адресов) и развертывания приложения WordPress.

Terraform создал эти ресурсы с помощью файлаmain.tf. В настоящее время все ресурсы в этом файле перечислены индивидуально. Чем сложнее становится ваша среда, тем больше ресурсов вам понадобится, и тем дольше и сложнее будет этот файл. Это усложнит управление вашей конфигурацией в долгосрочной перспективе.

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

Понимание модулей Terraform

Чтобы использовать собственное описание модулей Terraform:

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

Модули создают блоки многократно используемой инфраструктуры, которая может принимать входные данные и предоставлять выходные данные, как функция на языке программирования высокого уровня. Мы можем создавать модули, которые принимают необязательные входные аргументы для аналогичных элементов нашей инфраструктуры, а также устанавливают значения по умолчанию для этих входных параметров. Это помогает упорядочить и упростить вашу конфигурацию. Вы можете узнать больше о модулях вTerraform’s module documentation.

В качестве законченного примера взгляните на файлmain.tf. Последний раздел фактически уже использует модуль Terraform:

module "sippin_db" {
  source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
  ...
}

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

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

Этот модуль делает больше, чем просто создает одну каплю. Он создает теги Droplet, узлы кластера Galera, балансировщики нагрузки и плавающий IP. Вы можете думать о модулях terraform как о хорошем способе упаковки компонентов / или всего сервиса. Это также означает, что вы можете добавить больше ресурсов в модуль или создать выходные данные модуля, которые, в свою очередь, могут использоваться в качестве входных данных для других модулей, которые вы можете разрабатывать. Когда имеет смысл создать новый модуль, например, добавить новую услугу или какую-то вспомогательную функциональность, которую вы хотите отделить, вы можете абсолютно создать выходные данные в ваших модулях, и они будут сохранены как часть вашего состояния. Если вы используете удаленное состояние, выходные данные модуля могут быть очень полезны, когда вы хотите обмениваться информацией, доступной только для чтения, между различными компонентами вашей инфраструктуры или предоставлять внешней службе способ получения информации, которая может понадобиться.

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

Настройка инфраструктурных сред

В большинстве профессиональных проектов вы будете работать в трех разных средах: разработка, подготовка и производство.

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

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

Вот пример дерева каталогов, описывающий, как вы можете настроить изоляцию среды с помощью каталогов:

.
├── ansible.cfg
├── bin/
├── environments/
│   ├── config/
│   │   └── cloud-config.yaml
│   │
│   ├── dev/
│   ├── prod/
│   │   ├── config -> ../config
│   │   ├── group_vars
│   │   ├── host_vars
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   ├── terraform-inventory -> ../terraform-inventory
│   │   └── variables.tf
│   │
│   ├── staging/
│   │   ├── config -> ../config
│   │   ├── group_vars
│   │   ├── host_vars
│   │   ├── main.tf
│   │   ├── terraform.tfvars
│   │   ├── terraform-inventory -> ../terraform-inventory
│   │   └── variables.tf
│   │
│   └── terraform-inventory
│
├── site.yml
├── wordpress.yml
│
└── roles/

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

Например, в каталогеenvironments у нас есть подкаталог для каждой из трех сред, которые нам нужны:dev,staging иprod. Эта изоляция помогает предотвратить случайный запуск сценария Ansible или Terraform в неправильном месте. Вы можете сделать еще один шаг и использовать другой слой подкаталогов для хранения файлов для различных частей инфраструктуры каждой среды.

В сети естьmany great write-ups about this topic, одна из которых фактически превратилась в книгуTerraform: Up & Running Евгения Брикмана.

Использование версий модулей для сред

Модули Terraform также могут помочь вам внести изменения, не затрагивая другие среды. Например, взгляните на эти два модуля.

Один для промежуточной среды (например,staging/main.tf):

module "sippin_db" {
  source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.8"
  project          = "${var.project}"
  region           = "${var.region}"
  keys             = "${var.keys}"
  private_key_path = "${var.private_key_path}"
  ssh_fingerprint  = "${var.ssh_fingerprint}"
  public_key       = "${var.public_key}"
  ansible_user     = "${var.ansible_user}"
}

И один для производственной среды (например,prod/main.tf):

module "sippin_db" {
  source           = "github.com/cmndrsp0ck/galera-tf-mod.git?ref=v1.0.6"
  project          = "${var.project}"
  region           = "${var.region}"
  keys             = "${var.keys}"
  private_key_path = "${var.private_key_path}"
  ssh_fingerprint  = "${var.ssh_fingerprint}"
  public_key       = "${var.public_key}"
  ansible_user     = "${var.ansible_user}"
}

Единственное различие между ними - это значение ключаref в конце строкиsource, которое указывает версию для развертывания. В промежуточном режиме этоv1.0.8, а в производстве -v1.0.6. Использование контроля версий позволяет вносить и тестировать изменения в стадии подготовки перед развертыванием в рабочей среде, а подобные настройки упрощают конфигурацию, которая это поддерживает.

Прямо сейчас, практическая установка в предыдущем разделе не использует удаленное состояние. В главе 6 мы расскажем об использовании удаленного бэкэнда состояния (например, Consul), который является ключевым при работе в команде. Без удаленного бэкэнда состояния и вы, и другой член группы могли бы одновременно вносить изменения в инфраструктуру, вызывая конфликты, перебои или повреждение файла состояния.

Что дальше?

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

Related