Выходные значения: output
Выводы (output) — это способ Terraform сообщить наружу важные значения: IP сервера, URL базы, ARN роли. Они печатаются после apply и служат интерфейсом модулей.
Output — это публичный API вашей конфигурации. Что вы выводите — то и могут использовать другие: люди, скрипты, другие модули. Выводите ровно то, что нужно потребителю.
Блок output объявляет значение, которое Terraform покажет после apply и сохранит в state. Чаще всего это вычисленные атрибуты ресурсов, которые заранее не известны: публичный IP, доменное имя балансировщика, идентификатор созданной базы.
Объявление выводов
output "instance_ip" {
value = aws_instance.web.public_ip
description = "Публичный IP веб-сервера"
}
output "db_connection" {
value = aws_db_instance.main.endpoint
sensitive = true # не печатать в консоль
}
# можно собрать структуру
output "all_ips" {
value = { for k, vm in aws_instance.nodes : k => vm.private_ip }
}
Получить значение можно командой terraform output instance_ip или terraform output -json для машинного чтения. Это удобный мост в скрипты деплоя: IP=$(terraform output -raw instance_ip).
Как работает под капотом
Выводы вычисляются после создания ресурсов, когда их атрибуты уже известны. Terraform должен выстроить выводы в порядке их зависимостей друг от друга — это снова топосортировка, но уже на уровне output. Смоделируем сборку выводов, где один зависит от другого:
# атрибуты ресурсов после apply
attrs = {"web.public_ip": "54.1.2.3", "web.id": "i-0abc", "lb.dns": "lb.example.com"}
outputs = {
"ip": {"expr": lambda a: a["web.public_ip"], "deps": []},
"url": {"expr": lambda a, ip: f"http://{ip}", "deps": ["ip"]},
"dns": {"expr": lambda a: a["lb.dns"], "deps": []},
}
resolved = {}
def compute(name):
if name in resolved:
return resolved[name]
spec = outputs[name]
dep_vals = [compute(d) for d in spec["deps"]] # сперва зависимости
resolved[name] = spec["expr"](attrs, *dep_vals)
return resolved[name]
for name in outputs:
print(f" {name} = {compute(name)}")
«Попробуй сам ▶» — url зависит от ip, поэтому ip вычисляется первым. Так Terraform разрешает выводы.
Частые ошибки
- Вывод секретов без
sensitive. Пароль в открытом output попадёт в логи CI и историю терминала. - Слишком много выводов. Десятки выводов «на всякий случай» захламляют интерфейс модуля. Выводите нужное.
- Считать
sensitiveoutput защитой в state. Как и переменные, в state значение лежит открытым.
Best practices
- Выводы — это контракт модуля. Давайте им осмысленные имена и
description. - Для секретных выводов всегда ставьте
sensitive = true. - Для интеграции со скриптами используйте
terraform output -raw имяили-json.
Разбор глубже
Выводы играют особую роль, когда state одного проекта нужно прочитать из другого. Раньше для этого использовали data-источник terraform_remote_state, который читает чужой state и отдаёт его выводы. Сегодня это считается не лучшей практикой, потому что создаёт жёсткую связь между проектами и раскрывает всю внутреннюю структуру state. Современный подход — публиковать значения в нейтральное место (параметры SSM, переменные окружения), которое потребитель читает обычным data-источником, не зная ничего про чужой state. Но сам принцип «вывод = публичный интерфейс» остаётся: наружу отдаётся ровно то, что объявлено в output.
Практически выводы — это мост между Terraform и остальным миром автоматизации. После apply скрипт деплоя достаёт нужные значения командой terraform output -raw имя (флаг -raw печатает голую строку без кавычек, удобную для подстановки в переменную shell) или terraform output -json для машинного разбора целого набора. Поэтому к именованию выводов относятся как к проектированию API: db_endpoint понятнее, чем out1, а лишние выводы «на всякий случай» только захламляют интерфейс и сбивают потребителей с толку.
Полезно помнить и про зависимость выводов от ресурсов на уровне порядка операций. Поскольку вывод часто ссылается на вычисляемый атрибут, Terraform гарантирует, что он будет рассчитан только после успешного создания соответствующего ресурса. Это даёт приятное свойство: если apply упал на середине, выводы по уже созданным ресурсам всё равно будут корректны и доступны через terraform output. На этом строят надёжные скрипты деплоя, которые читают выводы поэтапно. А чтобы вывод не «протёк» в общий лог сборки, для всего, что хоть отдалённо напоминает секрет, по умолчанию ставят sensitive = true — дешевле перестраховаться, чем потом ротировать утёкший ключ.
Итог: output — публичный интерфейс конфигурации; значения вычисляются после apply в порядке их зависимостей. Дальше — как читать существующую инфраструктуру через data-источники.