Введение

Представьте, что вы архитектор и проектируете жилой район. Вы не стали бы создавать чертёж каждого дома с нуля, кирпич за кирпичом. Вместо этого вы разработали бы чертёж «стандартного дома» и просто использовали его 50 раз.

В Terraform такие повторно используемые чертежи называются модулями.

Модули — основной способ масштабировать Terraform от небольших примеров до реальных репозиториев инфраструктурного кода. Они позволяют командам один раз упаковать типовой шаблон и многократно его использовать.

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

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

Создайте каталог модуля

Сначала подготовьте место для хранения чертежей. Модули Terraform — это обычные каталоги с файлами Terraform.

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

По соглашению для порядка обычно создают каталог modules. Внутри него мы создадим каталог для конкретного модуля webserver.

Создайте такую структуру:

cd ~/project
mkdir -p modules/webserver

Проверьте результат:

ls -R

Вы должны увидеть каталог modules, содержащий каталог webserver. Этот каталог webserver будет самостоятельным небольшим проектом.

Определите модуль

Теперь запишите сам чертёж.

Модуль устроен так же, как корневой проект: файл main.tf определяет ресурсы, а файл variables.tf принимает входные данные.

В этой лабораторной работе мы будем использовать простой ресурс local_file. Он всего лишь создаёт текстовый файл на диске. Это удобно для изучения модулей: ресурс работает быстро и не требует сложной настройки облачной инфраструктуры.

Сначала создайте файл main.tf модуля с помощью nano:

nano modules/webserver/main.tf

Добавьте следующий текст. Он указывает Terraform создать файл с заданным содержимым.

resource "local_file" "server_config" {
  content  = "Server Name: ${var.server_name}\nEnvironment: ${var.env}"
  filename = "${path.root}/${var.server_name}-config.txt"
}

Сохраните файл и выйдите из nano (Ctrl+O, Enter, Ctrl+X).

Но что такое var.server_name? Мы ещё не определили эту переменную. Модуль должен объявить входные данные, которые он принимает, так же как функция в программировании.

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

Создайте файл variables.tf модуля:

nano modules/webserver/variables.tf

Добавьте следующие определения входных данных:

variable "server_name" {
  description = "The name of the server"
  type        = string
}

variable "env" {
  description = "The environment (e.g., dev, prod)"
  type        = string
  default     = "dev"
}

Сохраните файл и выйдите из nano.

Теперь наш чертёж, то есть модуль, готов. Он знает, как создать файл, и знает, какая информация ему нужна — имя и окружение.

Вызовите модуль

Теперь представим, что мы выполняем роль менеджера сайта. Нам нужно создать сервер, но мы не хотим заниматься деталями. Мы просто «нанимаем» модуль и поручаем ему эту работу.

Для этого добавьте блок module в корневой файл main.tf — тот, который находится в ~/project.

Создайте корневой файл main.tf:

cd ~/project
nano main.tf

Добавьте в него следующий блок, чтобы «вызвать» модуль:

module "my_first_server" {
  source      = "./modules/webserver"
  server_name = "web-01"
  env         = "production"
}

Не забудьте сохранить файл и выйти из nano.

Разберём этот блок:

  • module "my_first_server" — имя конкретного экземпляра модуля.
  • source — важный параметр. Он указывает Terraform, где находится каталог с чертежом (./modules/webserver).
  • server_name и env — входные данные, которые мы передаём модулю.

Таким образом, вызов модуля позволяет корневой конфигурации описать намерение на более высоком уровне. Вместо повторного ввода каждого ресурса низкого уровня вы говорите: «Создай экземпляр этого повторно используемого шаблона с такими входными данными».

ВАЖНО: после добавления нового модуля нужно сообщить Terraform, чтобы он подготовил его. Выполните init, чтобы установить модуль:

terraform init

Теперь примените конфигурацию:

terraform apply -auto-approve

Проверьте результат. Модуль должен создать новый файл:

cat web-01-config.txt

Успешно! Модуль получил входные данные ("web-01" и "production") и выполнил работу за нас.

Повторно используйте модуль

Здесь и проявляется главное преимущество модулей. Нам нужен второй сервер. Вместо копирования всего кода ресурса мы ещё раз создадим экземпляр чертежа.

Снова откройте корневой файл main.tf с помощью nano:

nano main.tf

С помощью клавиш со стрелками перейдите в конец файла и добавьте следующий блок:

module "my_second_server" {
  source      = "./modules/webserver"
  server_name = "web-02"
  ## We are not setting 'env' here, so it will use the default value "dev"
}

Сохраните файл и выйдите из nano.

Обратите внимание, как просто выглядит эта конфигурация. Мы лишь указываем: «Мне нужен ещё один сервер с именем web-02». Нам не нужно знать, как внутри работает local_file. Мы используем только интерфейс модуля.

Примените изменения:

terraform init
terraform apply -auto-approve

Убедитесь, что теперь существуют два отдельных файла серверов:

ls -l *-config.txt

Проверьте, что для второго сервера использовалось окружение по умолчанию "dev":

cat web-02-config.txt

Теперь вы освоили основной принцип повторно используемой инфраструктуры!

Итоги

Поздравляем! Вы сделали большой шаг к написанию профессионального кода Terraform.

В этой лабораторной работе вы узнали:

  • Модули — как группировать код в повторно используемые каталоги, то есть в «чертежи».
  • Входные данные — как использовать переменные, чтобы сделать модули гибкими.
  • Вызов модулей — как использовать блок module для создания экземпляров чертежа.
  • Повторное использование — как создавать несколько копий инфраструктуры с минимальным количеством кода.

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