Автор выбрал Фонд свободного и открытого исходного кода для получения пожертвования в рамках программы Напиши в обмен на пожертвования.
Введение
Модули Terraform позволяют группировать различные ресурсы вашей инфраструктуры в единый, объединенный ресурс. Вы можете повторно использовать их позже с возможными настройками без повторения определений ресурсов каждый раз, когда они вам нужны, что полезно для больших и сложно структурированных проектов. Вы можете настраивать экземпляры модулей, используя определенные вами входные переменные, а также извлекать информацию из них с помощью выводов. Помимо создания собственных пользовательских модулей, вы также можете использовать заранее созданные модули, опубликованные public на Реестре Terraform. Разработчики могут использовать и настраивать их с использованием вводных данных, так же как модули, которые вы создаете, но их исходный код хранится и извлекается из облака.
В этом руководстве вы создадите модуль Terraform, который настроит несколько Droplets за балансировщиком нагрузки для обеспечения избыточности. Вы также будете использовать функции циклического перебора for_each
и count
языка конфигурации HashiCorp (HCL), чтобы развернуть несколько настроенных экземпляров модуля одновременно.
Предварительные требования
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean control panel. You can find instructions in the DigitalOcean product document, How to Create a Personal Access Token.
- Установленный Terraform на вашем локальном компьютере и настроенный проект с провайдером DO. Завершите Шаг 1 и Шаг 2 руководства Как использовать Terraform с DigitalOcean и убедитесь, что название папки проекта
terraform-modules
, а неloadbalance
. Во время Шага 2 не включайте переменнуюpvt_key
и ресурс SSH-ключа. - Знакомство с типами данных HCL и циклами. Дополнительную информацию можно найти в руководстве Как улучшить гибкость с помощью переменных, зависимостей и условий Terraform.
- Знакомство с выводами Terraform и их использованием. Вы можете следовать руководству Как управлять данными инфраструктуры с помощью выводов Terraform, чтобы узнать о них.
Примечание: Этот учебный материал был специально протестирован с Terraform 1.1.3
.
Структура модуля и преимущества
В этом разделе вы узнаете, какие преимущества приносят модули, где обычно размещаются в проекте и как их следует структурировать.
Пользовательские модули Terraform создаются для инкапсуляции связанных компонентов, которые часто используются и разворачиваются вместе в более крупных проектах. Они являются автономными, упаковывая только необходимые ресурсы, переменные и провайдеры.
Модули обычно хранятся в центральной папке в корне проекта, каждый в своей соответствующей подпапке. Для того чтобы сохранить чистое разделение между модулями, всегда проектируйте их с единственной целью и убедитесь, что они никогда не содержат подмодулей.
Полезно создавать модули из ваших схем ресурсов, когда вы обнаруживаете, что повторяете их с редкими настройками. Упаковка одного ресурса как модуля может быть избыточной и постепенно снимает простоту общей архитектуры.
Для небольших разработочных и тестовых проектов включение модулей не является необходимым, поскольку они не приносят много улучшений в таких случаях. Благодаря их возможности настройки модули являются строительным элементом сложно структурированных проектов. Разработчики используют модули для крупных проектов из-за значительных преимуществ в избежании дублирования кода. Модули также предлагают преимущество в том, что определения нужно изменять только в одном месте, после чего они будут распространяться по остальной части инфраструктуры.
Следующим шагом будет определение, использование и настройка модулей в ваших проектах Terraform.
Создание модуля
В этом разделе вы определите несколько Droplets и балансировщик нагрузки в качестве ресурсов Terraform и упакуете их в модуль. Вы также сделаете получившийся модуль настраиваемым с помощью входных данных модуля.
Вы сохраните модуль в каталоге с именем droplet-lb
, внутри каталога с именем modules
. Предполагая, что вы находитесь в каталоге terraform-modules
, который вы создали как часть предварительных требований, создайте оба одновременно, выполнив следующую команду:
Аргумент -p
указывает mkdir
создать все каталоги в указанном пути.
Перейдите в него:
Как отмечалось в предыдущем разделе, модули содержат ресурсы и переменные, которые они используют. Начиная с Terraform 0.13
, в них также должны включаться определения провайдеров, которые они используют. Модули не требуют какой-либо специальной конфигурации, чтобы отметить, что код представляет собой модуль, так как Terraform рассматривает каждый каталог, содержащий код HCL, как модуль, даже корневой каталог проекта.
Переменные, определенные в модуле, отображаются как его входные данные и могут быть использованы в определениях ресурсов для настройки их. Создайте и откройте для редактирования файл с именем variables.tf
, в котором вы будете хранить переменные:
Добавьте следующие строки:
Сохраните и закройте файл.
Вы сохраните определение Droplet в файле с именем droplets.tf
. Создайте и откройте его для редактирования:
Добавьте следующие строки:
Для параметра count
, который определяет количество экземпляров ресурса для создания, вы передаете переменную droplet_count
. Ее значение будет указано при вызове модуля из основного кода проекта. Имена каждого развернутого Droplet будут отличаться, что вы достигаете, добавив индекс текущего Droplet к предоставленному имени группы. Развертывание Droplets будет в регионе fra1
, и они будут работать под управлением Ubuntu 20.04.
Когда закончите, сохраните и закройте файл.
Теперь, когда Droplets определены, вы можете перейти к созданию балансировщика нагрузки. Вы сохраните определение его ресурса в файле с именем lb.tf
. Создайте и откройте его для редактирования, выполнив следующую команду:
Добавьте определение его ресурса:
Вы определяете балансировщик нагрузки с именем группы в его имени, чтобы сделать его различимым. Вы развертываете его в регионе fra1
вместе с Droplets. Следующие два раздела указывают целевые и контрольные порты и протоколы.
Выделенный блок droplet_ids
принимает идентификаторы Droplet, которые должны управляться балансировщиком нагрузки. Поскольку Droplet’ов может быть несколько, и их количество заранее неизвестно, вы используете цикл for
для обхода коллекции Droplet’ов (digitalocean_droplet.droplets
) и получения их идентификаторов. Вы окружаете цикл for
квадратными скобками ([]
), чтобы результирующая коллекция была списком.
Сохраните и закройте файл.
Теперь вы определили Droplet, балансировщик нагрузки и переменные для вашего модуля. Вам нужно определить требования к провайдеру, указав, какие провайдеры использует модуль, включая их версию и расположение. С версии Terraform 0.13
, модули должны явно определять источники используемых ими провайдеров, не поддерживаемых HashiCorp; это связано с тем, что они не наследуют их от родительского проекта.
Вы сохраните требования к провайдеру в файл с именем provider.tf
. Создайте его для редактирования, запустив:
Добавьте следующие строки, чтобы требовать провайдер digitalocean
:
Сохраните и закройте файл, когда закончите. Модуль droplet-lb
теперь требует провайдер digitalocean
.
Модули также поддерживают выводы, которые вы можете использовать для извлечения внутренней информации о состоянии их ресурсов. Вы определите вывод, который предоставляет IP-адрес балансировщика нагрузки, и сохраните его в файле с именем outputs.tf
. Создайте его для редактирования:
Добавьте следующее определение:
Этот вывод извлекает IP-адрес балансировщика нагрузки. Сохраните и закройте файл.
Модуль droplet-lb
теперь функционально завершен и готов к развертыванию. Вы будете вызывать его из основного кода, который вы сохраните в корне проекта. Сначала перейдите к нему, двигаясь вверх по вашему файловому каталогу дважды:
Затем создайте и откройте для редактирования файл с именем main.tf
, в котором вы будете использовать модуль:
Добавьте следующие строки:
В этом объявлении вы вызываете модуль droplet-lb
, расположенный в указанной директории source
. Вы настраиваете входные данные, которые он предоставляет, droplet_count
и group_name
, которые установлены на group1
, чтобы позже вы могли различать между экземплярами.
Поскольку вывод IP-адреса балансировщика нагрузки определен в модуле, он не будет автоматически отображаться при применении проекта. Решением этой проблемы является создание другого вывода, получающего его значение (loadbalancer_ip
).
Сохраните и закройте файл, когда закончите.
Инициализируйте модуль, запустив:
Вывод будет выглядеть так:
OutputInitializing modules...
- groups in modules/droplet-lb
Initializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Installing digitalocean/digitalocean v2.19.0...
- Installed digitalocean/digitalocean v2.19.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Вы можете попробовать спланировать проект, чтобы увидеть, какие действия предпримет Terraform, запустив:
Вывод будет похож на это:
Этот вывод подробно описывает, что Terraform создаст три Droplets с именами group1-0
, group1-1
и group1-2
, а также создаст балансировщик нагрузки с именем group1-lb
, который будет управлять трафиком к и от трех Droplets.
Вы можете попробовать применить проект к облаку, запустив:
Введите yes
, когда будете подтверждены. В выводе будут показаны все действия, и также будет показан IP-адрес балансировщика нагрузки:
Вы создали модуль, содержащий настраиваемое количество Droplets и балансировщик нагрузки, который будет автоматически настроен для управления входящим и исходящим трафиком.
Переименование развернутых ресурсов
В предыдущем разделе вы развернули модуль, который определили и назвали groups
. Если вы когда-нибудь захотите изменить его имя, простое переименование вызова модуля не приведет к ожидаемым результатам. Переименование вызова заставит Terraform разрушить и воссоздать ресурсы, что приведет к избыточному времени простоя.
Например, откройте main.tf
для редактирования, запустив:
Переименуйте модуль groups
в groups_renamed
, как показано ниже:
Сохраните и закройте файл. Затем снова инициализируйте проект:
Теперь вы можете спланировать проект:
Вывод будет длинным, но будет выглядеть примерно так:
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] будет уничтожен
...
# module.groups_renamed.digitalocean_droplet.droplets[0] будет создан
...
Terraform предложит вам уничтожить существующие экземпляры и создать новые. Это разрушительно и необоснованно, и может привести к нежелательному простою.
Вместо этого, используя блок moved
, вы можете указать Terraform переместить старые ресурсы под новым именем. Откройте main.tf
для редактирования и добавьте следующие строки в конец файла:
После завершения сохраните и закройте файл.
Теперь вы можете спланировать проект:
Когда вы планируете с блоком moved
в main.tf
, Terraform хочет переместить ресурсы, а не создавать их заново:
OutputTerraform will perform the following actions:
# Модуль module.groups.digitalocean_droplet.droplets[0] был перемещен в module.groups_renamed.digitalocean_droplet.droplets[0]
...
# Модуль module.groups.digitalocean_droplet.droplets[1] был перемещен в module.groups_renamed.digitalocean_droplet.droplets[1]
...
Перемещение ресурсов изменяет их положение в состоянии Terraform, что означает, что фактические облачные ресурсы не будут изменены, уничтожены или созданы заново.
Поскольку вы собираетесь значительно изменить конфигурацию на следующем этапе, уничтожьте развернутые ресурсы, выполнив следующую команду:
Введите yes
, когда будете призваны. Результат будет следующим:
Output...
Destroy complete! Resources: 4 destroyed.
На этом этапе вы переименовали ресурсы в вашем проекте Terraform, не уничтожая их в процессе. Теперь вы будете развертывать несколько экземпляров модуля из одного и того же кода, используя for_each
и count
.
Развертывание нескольких экземпляров модуля
На этом этапе вы будете использовать count
и for_each
, чтобы развернуть модуль droplet-lb
несколько раз с настройками по умолчанию.
Использование count
Один из способов развертывания нескольких экземпляров одного и того же модуля сразу – передать количество в параметр count
, который автоматически доступен для каждого модуля. Откройте main.tf
для редактирования:
Измените его, чтобы он выглядел так, удалив существующее определение вывода и блок moved
:
Установив count
в 3
, вы указываете Terraform развернуть модуль три раза, каждый раз с другим именем группы. Когда закончите, сохраните и закройте файл.
Запланируйте развертывание, запустив:
Вывод будет длинным и будет выглядеть так:
Подробности Terraform в выводе, что каждый из трех экземпляров модуля будет иметь три Droplet и связанный с ними балансировщик нагрузки.
Используя for_each
Вы можете использовать for_each
для модулей, когда требуется более сложная настройка экземпляра, или когда количество экземпляров зависит от данных стороннего поставщика (часто представленных в виде карт), которые неизвестны при написании кода.
Теперь вы определите карту, которая сопоставляет имена групп с количеством Droplet и развернете экземпляры droplet-lb
в соответствии с ней. Откройте main.tf
для редактирования, запустив:
Измените файл, чтобы он выглядел так:
Сначала вы определяете карту с именем group_counts
, которая содержит количество Droplet для данной группы. Затем вы вызываете модуль droplet-lb
, но указываете, что цикл for_each
должен работать на var.group_counts
, карту, которую вы определили сразу перед этим. droplet_count
принимает each.value
, значение текущей пары, которое является количеством Droplet для текущей группы. group_name
получает имя группы.
Сохраните и закройте файл, когда закончите.
Попробуйте применить конфигурацию, запустив:
В выводе будут подробно описаны действия, которые Terraform выполнит для создания двух групп с их Droplet и балансировщиками нагрузки:
На этом этапе вы использовали count
и for_each
для развертывания нескольких настраиваемых экземпляров одного и того же модуля из одного и того же кода.
Вывод
В этом руководстве вы создали и развернули модули Terraform. Вы использовали модули для группировки логически связанных ресурсов вместе и настраивали их, чтобы развернуть несколько разных экземпляров из центрального определения кода. Вы также использовали выводы, чтобы показать атрибуты ресурсов, содержащихся в модуле.
Если вы хотите узнать больше о Terraform, посмотрите нашу серию Как управлять инфраструктурой с помощью Terraform.
Source:
https://www.digitalocean.com/community/tutorials/how-to-build-a-custom-terraform-module