Реализация модулей Terraform

LinuxBeginner
Практиковаться сейчас

Введение

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

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

К концу этой лабораторной работы вы получите практическое понимание того, как создавать и использовать собственные модули Terraform.

Создайте каталог modules в корне проекта

На этом шаге вы создадите стандартную структуру каталогов для локального модуля Terraform. Общепринятой практикой является размещение всех локальных модулей внутри каталога modules в корне вашего проекта. Каждый подкаталог внутри modules затем представляет собой один, автономный модуль.

Сначала давайте создадим каталог для наших модулей и специальный подкаталог для модуля, который мы назовем localfile_creator. Все операции будут выполняться в каталоге ~/project.

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

mkdir -p modules/localfile_creator

Флаг -p гарантирует, что mkdir создаст родительский каталог modules, если он еще не существует.

Теперь вы можете проверить, что каталоги созданы правильно, используя команду tree. Если tree не установлен, вы можете использовать ls -R.

tree

Вы должны увидеть следующий вывод, подтверждающий вашу новую структуру каталогов:

.
└── modules
    └── localfile_creator

2 directories, 0 files

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

Создайте файл main.tf в модуле для ресурса local_file

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

Мы определим ресурс local_file, который является частью провайдера hashicorp/local. Этот ресурс отлично подходит для учебных целей, поскольку он просто управляет файлами в локальной файловой системе и не требует учетных данных облачного провайдера.

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

nano modules/localfile_creator/main.tf

Теперь добавьте следующий код на языке HCL (HashiCorp Configuration Language) в файл. Этот код определяет ресурс типа local_file с локальным именем example.

resource "local_file" "example" {
  content  = "This is a file created by a Terraform module."
  filename = "${path.module}/module_output.txt"
}

Давайте разберем этот код:

  • resource "local_file" "example": Это объявляет ресурс типа local_file и присваивает ему локальное имя example.
  • content: Этот аргумент устанавливает содержимое, которое будет записано в файл.
  • filename: Этот аргумент указывает путь и имя создаваемого файла. Мы используем встроенную переменную path.module, которая всегда ссылается на путь файловой системы модуля, где размещено выражение. Это делает путь к файлу относительным самому модулю.

Сохраните файл и выйдите из nano, нажав Ctrl+X, затем Y и Enter.

Определите переменные и выходы модуля

На этом шаге вы сделаете ваш модуль настраиваемым и способным возвращать информацию. Жесткое кодирование значений, таких как имена файлов и содержимое, ограничивает возможность повторного использования модуля. Мы будем использовать входные переменные (input variables) для передачи настраиваемых значений и выходные значения (output values) для предоставления информации о ресурсах, создаваемых модулем.

По соглашению, переменные определяются в файле variables.tf, а выходы — в файле outputs.tf.

Сначала создайте файл variables.tf для вашего модуля:

nano modules/localfile_creator/variables.tf

Добавьте следующий код для определения двух входных переменных: file_content и file_name.

variable "file_content" {
  description = "The content of the file."
  type        = string
  default     = "Default content."
}

variable "file_name" {
  description = "The name of the file to create."
  type        = string
}

Далее создайте файл outputs.tf, чтобы объявить, какую информацию будет возвращать модуль:

nano modules/localfile_creator/outputs.tf

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

output "filename" {
  description = "The full path to the created file."
  value       = local_file.example.filename
}

Наконец, вам необходимо обновить файл main.tf модуля, чтобы использовать эти новые переменные вместо жестко закодированных значений. Снова откройте файл:

nano modules/localfile_creator/main.tf

Измените файл так, чтобы он выглядел следующим образом. Мы заменяем жестко закодированные строки на var.file_content и var.file_name.

resource "local_file" "example" {
  content  = var.file_content
  filename = "${path.module}/${var.file_name}"
}

Сохраните и выйдите из редактора. Ваш модуль теперь гибок и готов к использованию с различными входными данными.

Вызов модуля в корневом файле main.tf

На этом шаге вы создадите корневой конфигурационный файл, который вызывает только что созданный вами модуль. Корневой файл main.tf является точкой входа для выполнения Terraform. Именно здесь вы компонуете свою инфраструктуру, вызывая один или несколько модулей.

Теперь вы будете работать в корневой директории вашего проекта, ~/project. Создайте здесь файл main.tf:

nano main.tf

Добавьте следующий код в этот файл. Эта конфигурация будет использовать модуль localfile_creator.

terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "2.4.0"
    }
  }
}

module "file_creator_instance" {
  source = "./modules/localfile_creator"

  file_content = "Hello from the root module!"
  file_name    = "my_test_file.txt"
}

output "created_file_path" {
  description = "Path of the file created by the module."
  value       = module.file_creator_instance.filename
}

Проанализируем эту корневую конфигурацию:

  • terraform { ... }: Этот блок определяет требования к провайдерам (provider requirements). Поскольку наш модуль использует провайдер local, корневой модуль, который его вызывает, также должен его объявить.
  • module "file_creator_instance" { ... }: Это блок модуля. file_creator_instance — это локальное имя для данного конкретного экземпляра модуля.
  • source = "./modules/localfile_creator": Это указывает Terraform, где найти исходный код модуля. В данном случае это локальный путь.
  • file_content = "..." и file_name = "...": Здесь вы передаете значения входным переменным, определенным в variables.tf модуля.
  • output "created_file_path" { ... }: Этот блок вывода корневого уровня извлекает значение из модуля. Синтаксис: module.<ИМЯ_ЭКЗЕМПЛЯРА_МОДУЛЯ>.<ИМЯ_ВЫХОДА>.

Сохраните файл и выйдите из nano. Ваш проект теперь полностью настроен для использования модуля.

Выполните terraform apply для развертывания через модуль

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

Сначала инициализируйте рабочую директорию Terraform. Эта команда загружает необходимые плагины провайдеров (в данном случае, hashicorp/local).

terraform init

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

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/local versions matching "2.4.0"...
- Installing hashicorp/local v2.4.0...
- Installed hashicorp/local v2.4.0 (signed by HashiCorp)

Terraform has been successfully initialized!
...

Далее выполните terraform plan, чтобы увидеть, какие изменения внесет Terraform. Это "сухой запуск" (dry run), который ничего не меняет, но показывает вам план выполнения.

terraform plan

Вывод покажет, что будет создан один ресурс (это local_file внутри вашего модуля).

...
Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + created_file_path = (known after apply)
...

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

terraform apply -auto-approve

Terraform выполнит план и создаст файл. Вывод подтвердит создание и отобразит определенное вами выходное значение.

...
module.file_creator_instance.local_file.example: Creating...
module.file_creator_instance.local_file.example: Creation complete after 0s [id=f73598097552a798110a31388c54c1194b539a53]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

created_file_path = "./modules/localfile_creator/my_test_file.txt"

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

ls -l modules/localfile_creator/
cat modules/localfile_creator/my_test_file.txt

Вывод команды cat должен быть следующим:

Hello from the root module!

Поздравляем, вы успешно создали и использовали модуль Terraform!

Резюме

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

Вы научились:

  • Создавать стандартную структуру каталогов для локальных модулей.
  • Определять ресурсы в файле main.tf модуля.
  • Использовать variables.tf для обеспечения настраиваемости и многократного использования вашего модуля.
  • Использовать outputs.tf для предоставления данных из вашего модуля вызывающей конфигурации.
  • Вызывать локальный модуль из корневого файла main.tf, передавая входные переменные и получая доступ к выходным значениям.
  • Применять конфигурацию, чтобы увидеть модуль в действии.

Освоив модули, вы сможете писать более чистый, организованный и масштабируемый код инфраструктуры как код (Infrastructure as Code). Отличная работа по завершению этой лабораторной работы!