Когда включать TF_LOG
По умолчанию Terraform говорит мало. План, это пара десятков строк, apply, список созданных ресурсов и итог. Если что-то падает, получаешь короткое сообщение об ошибке и всё.
В трёх случаях этого не хватает:
- Apply виснет. Не падает с ошибкой, просто ничего не происходит минутами. Где он сейчас застрял? В каком ресурсе?
- Странная ошибка от провайдера. «InvalidParameter», какой параметр? Какой API-вызов? С какими данными?
- Подозрение что что-то не так с зависимостями. Почему ресурс A создаётся раньше B?
Для всего этого, TF_LOG.
Уровни
Пять уровней, от шумного к тихому:
| Уровень | Что попадает | Когда нужен |
|---|---|---|
TRACE | Каждая внутренняя операция, все HTTP-запросы целиком | Когда дебажат сам Terraform или провайдер |
DEBUG | Важные шаги, краткие HTTP-метаданные | Большинство дебаг-задач |
INFO | Старт-стоп фаз, провайдер версии | Стандартный «расскажи что делаешь» |
WARN | Только предупреждения | Не для дебага, для прода |
ERROR | Только ошибки | По умолчанию для CLI |
Практически всегда. DEBUG. TRACE даёт мегабайты вывода, который читать невозможно без grep'а.
Базовое использование
Linux/macOS:
TF_LOG=DEBUG terraform apply
Windows PowerShell:
$env:TF_LOG="DEBUG"
terraform apply
Windows cmd:
set TF_LOG=DEBUG
terraform apply
Вывод сразу станет на порядок длиннее, все внутренние шаги печатаются в stderr.
TF_LOG_PATH, сохранить в файл
Логи DEBUG-уровня, это сотни строк на каждый ресурс. Читать в терминале невозможно. Решение:
TF_LOG=DEBUG TF_LOG_PATH=/tmp/tf.log terraform apply
После apply, /tmp/tf.log содержит весь дебаг-вывод. Открой
редактором или less/grep.
Файл дописывается, не перезаписывается. Несколько apply подряд,
логи смешиваются. Если хочется чистый файл, rm /tmp/tf.log до
запуска.
TF_LOG_PROVIDER и TF_LOG_CORE
Иногда нужны логи только от провайдера (AWS-плагина), без внутренностей Terraform:
TF_LOG_PROVIDER=DEBUG terraform apply # только провайдеры
TF_LOG_CORE=DEBUG terraform apply # только ядро
TF_LOG=DEBUG terraform apply # всё
Это сильно сокращает объём при дебаге AWS-API-проблем.
Что искать в логах
HTTP-запросы к облаку
---[ REQUEST ]-------------------------------------
PUT /linuxlab-hello-abc/ HTTP/1.1
Host: s3.amazonaws.com
Authorization: AWS4-HMAC-SHA256 ...
Каждый создаваемый ресурс, это один или несколько HTTP-запросов. Если apply виснет. Это последний REQUEST без ответа покажет где.
Ответы с ошибками
---[ RESPONSE ]------------------------------------
HTTP/1.1 400 Bad Request
...
<Error>
<Code>InvalidBucketName</Code>
<Message>The specified bucket is not valid.</Message>
</Error>
Это исходное сообщение от облака, не отфильтрованное Terraform. Иногда оно понятнее.
Разрешение зависимостей
[DEBUG] ReferenceTransformer: "aws_s3_bucket.demo" references: [random_id.suffix]
[DEBUG] Starting graph walk: walkApply
Видно граф зависимостей в действии. Если ожидаешь что A зависит от
B, а в логах этого нет, implicit dependency не сработала, нужен
depends_on.
Acquiring/Releasing lock
[DEBUG] Acquiring state lock. This may take a few moments...
[DEBUG] backend/local: state lock acquired
Если apply виснет на «Acquiring state lock», кто-то другой держит
lock. См. terraform force-unlock, но осторожно.
Полезные паттерны фильтрации
Только HTTP-запросы:
TF_LOG=DEBUG terraform apply 2>&1 | grep -E '^(PUT|GET|POST|DELETE)'
Только ошибки:
TF_LOG=DEBUG terraform apply 2>&1 | grep -iE '(error|fail|denied)'
Запросы и ответы конкретного типа ресурса:
grep -A 5 's3' /tmp/tf.log
Отключить логирование
unset TF_LOG TF_LOG_PATH # Linux/macOS
Remove-Item Env:\TF_LOG # PowerShell
Или просто открыть новую сессию терминала.
Подводные камни
-
TRACE даёт гигабайты на средних проектах. Не запускай TRACE без
TF_LOG_PATH, терминал зальёт. -
Логи содержат секреты. API-ключи в HTTP-заголовках, пароли БД в request body. Не отправляй raw-логи в багтрекеры HashiCorp без редактирования.
-
TF_LOG не помогает с битым HCL. Если синтаксис плохой. Terraform упадёт до запуска. Дебаг нужен для runtime-ошибок.
-
DEBUG в CI замедляет сборку. Пишет в stderr много, замусоривает логи job'а. Включать только когда этот job упал, не на всё CI.
-
Логи провайдеров, на английском. Никакой локализации, даже если TF CLI в LC_ALL=ru_RU. Все ошибки от AWS-API будут на en.
-
Перенаправление 2>&1 нужно для большинства фильтров. TF пишет дебаг в stderr, основной вывод, в stdout. Без
2>&1grep ничего не найдёт.
См. также в LinuxLab
- file-descriptors, почему
2>&1надо ставить ПОСЛЕ команды и до пайпа, а не куда попало; что такое stderr/stdout как файловые дескрипторы. - cmd-journalctl, если запускаешь
terraform под systemd-таймером, логи
TF_LOG_PATHидут в файл, а остальное, в journal. Удобный baseline для долгоиграющих pipeline. - bash-scripting, оборачивать
TF_LOG=DEBUG …в утилитарный скрипт чище, чем каждый раз выставлять env-переменные руками.