Введение
Представьте, что вы заказываете кофе. Если в меню написано только «Кофе», вы, скорее всего, каждый раз будете получать чёрный кофе. Но если в меню есть параметры «Размер» или «Тип молока», вы можете настроить заказ, и бариста не придётся осваивать новый рецепт для каждой возможной комбинации.
В Terraform переменные делают конфигурации повторно используемыми: входные значения можно изменять, не переписывая весь файл.
Выходные значения позволяют Terraform сообщать важные результаты, например идентификаторы, имена или адреса. Вместе переменные и выходные значения делают конфигурации Terraform более модульными и практичными.
К концу этой лабораторной работы у вас будет гибкая конфигурация Terraform, которая сможет создавать контейнеры с разными именами по вашему запросу.
Переменные отделяют логику конфигурации от данных, зависящих от конкретной среды. Выходные значения выполняют обратную задачу: публикуют полезные результаты для пользователя или последующих этапов автоматизации.
Создайте файл переменных
Хорошие повара подготавливают ингредиенты до начала готовки. В Terraform рекомендуется хранить настраиваемые параметры (переменные) в отдельном файле, а не в основном «рецепте».
Стандартное имя такого файла — variables.tf. Создание этого файла не изменяет принцип работы Terraform: Terraform читает все файлы .tf в папке так, будто это одна большая книга. Однако отдельный файл помогает поддерживать порядок.
Этот принцип организации особенно важен для IaC, поскольку реальные конфигурации быстро разрастаются. Чёткое разделение переменных, ресурсов и выходных значений значительно упрощает дальнейшее обслуживание.
Перейдите в папку проекта и создайте файл:
cd ~/project
touch variables.tf
Теперь у нас есть пустой файл, готовый для объявлений. На следующем шаге мы добавим в него содержимое.
Объявите переменную
Теперь нужно объявить доступные параметры. Это похоже на добавление поля «Имя» в форму заказа.
Откройте variables.tf с помощью nano:
nano variables.tf
Добавьте следующий блок. Он сообщает Terraform: «Существует параметр container_name, принимающий текстовое значение (string). Если пользователь ничего не укажет, используйте имя ExampleNginxContainer».
variable "container_name" {
description = "Value of the name for the Docker container"
type = string
default = "ExampleNginxContainer"
}
Сохраните файл и выйдите из nano (Ctrl+O, Enter, Ctrl+X).
Теперь, когда поле формы создано, нужно использовать его в нашем «рецепте». Для этого создадим файл main.tf, который будет обращаться к этой переменной.
Создайте main.tf:
nano main.tf
Вставьте следующий код. Обратите внимание на строку name = var.container_name. Так переменная подключается к конфигурации.
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = var.container_name
ports {
internal = 80
external = 8000
}
}
Не забудьте сохранить файл и выйти из nano.
Используя var.container_name, мы говорим Terraform: «Не задавай имя напрямую. Найди значение переменной container_name и используй его».
Определите выходные значения
Когда вы что-то покупаете, вы получаете чек. В Terraform выходные значения выполняют похожую роль: они показывают важные сведения о только что созданных ресурсах.
Это особенно полезно для получения данных, которые невозможно узнать до создания ресурса, например случайного идентификатора, назначенного системой, или публичного IP-адреса.
Выходные значения особенно полезны, когда один компонент инфраструктуры должен передать сведения оператору, другому модулю Terraform или следующему этапу автоматизации.
Создадим файл outputs.tf, чтобы хранить в нём эти возвращаемые значения. Откройте его с помощью nano:
nano outputs.tf
Добавьте следующий блок. Он сообщает Terraform: «После завершения выведите идентификатор контейнера nginx».
output "container_id" {
description = "ID of the Docker container"
value = docker_container.nginx.id
}
Сохраните файл и выйдите из nano.
Теперь запустим код.
Сначала инициализируйте проект, чтобы загрузить провайдер Docker:
terraform init
Затем примените конфигурацию. Мы не будем указывать имя контейнера, поэтому будет использовано значение по умолчанию (ExampleNginxContainer). Параметр -auto-approve пропускает запрос подтверждения «yes» и экономит время.
terraform apply -auto-approve
Посмотрите на самую нижнюю часть вывода. Вы должны увидеть Outputs:, а сразу после него — значение container_id.
Переопределите переменные
Главное преимущество переменных — возможность изменять их без переписывания кода. Представьте, что вы хотите запустить второй контейнер с другим именем. Редактировать main.tf не нужно.
Просто сообщите Terraform новое значение с помощью флага -var. Это похоже на просьбу к бариста: «Вообще-то, приготовьте большой».
Выполните команду:
terraform apply -var="container_name=MyDynamicContainer" -auto-approve
Внимательно следите за выводом. Terraform сообщит: docker_container.nginx must be replaced.
Почему это происходит? В Docker нельзя легко переименовать работающий контейнер. Чтобы изменить имя, Terraform решает удалить старый контейнер (-) и создать новый (+) с новым именем. Это важный принцип неизменяемой инфраструктуры: вместо исправления существующих объектов мы заменяем их.
Проверьте, что новый контейнер запущен:
docker ps --format "{{.Names}}"
В выводе должно появиться MyDynamicContainer.
Итоги
Поздравляем! Вы успешно сделали код Terraform динамическим.
В этой лабораторной работе вы узнали:
- Переменные: как использовать
variables.tfдля создания гибких «полей формы» в коде. - Ссылки: как использовать
var.variable_name, чтобы вставлять эти значения в основную конфигурацию. - Выходные значения: как использовать
outputs.tfдля отображения важных данных (своеобразного «чека») после выполнения конфигурации. - Переопределение значений: как вводить новые значения из командной строки с помощью
-var, повторно используя один и тот же код в разных ситуациях.



