terraform validate — одна из первых команд, которые осваивают пользователи Terraform, и одновременно одна из самых непонятых. Он не подключается ни к одному облачному провайдеру. Он не проверяет, допустимы ли значения ваших ресурсов в реальном мире. Он не смотрит в файл состояния. То, что он делает, быстро, безопасно и необходимо, но понимание того, где именно он останавливается, отличает надёжный конвейер CI от ложного чувства безопасности перед terraform apply.
Что такое terraform validate
terraform validate — встроенная подкоманда Terraform, выполняющая статический анализ ваших файлов конфигурации. Она читает каждый файл .tf и .tfvars в текущем рабочем каталоге (и рекурсивно все локальные модули), разбирает их и проверяет, является ли конфигурация внутренне согласованной и структурно корректной.
Статический анализ, а не выполнение
Ключевая особенность terraform validate в том, что он полностью статичен. Сетевые подключения не выполняются, API провайдеров не вызываются, файл состояния не читается. Проверка целиком происходит в памяти на машине, где запущена команда. Поэтому её безопасно запускать в любой среде, включая CI-раннеры без облачных учётных данных, и она завершается менее чем за две секунды на большинстве реальных конфигураций.
Это отличается от terraform plan, который выполняет те же статические проверки, а затем подключается к API провайдеров, чтобы вычислить разницу с реальной инфраструктурой. Validate — лёгкий первый фильтр; plan — исчерпывающий фильтр перед применением. Запуск обоих по очереди даёт самую широкую проверку перед тем, как вы согласитесь на изменение инфраструктуры.
Note
Три режима работы
- Обычный режим — запускается после terraform init; проверяет синтаксис, схему по скачанным плагинам провайдеров и ссылки между файлами
- Без init — если каталога .terraform нет, validate всё равно запускается, но пропускает проверки схемы провайдеров и сообщает только об ошибках разбора HCL и проблемах ссылок, которые можно разрешить без метаданных провайдеров
- Режим JSON (-json) — выводит структурированный объект JSON с булевым valid, целым error_count и массивом diagnostics, подходящий для разбора в CI и интеграций с редакторами
Что terraform validate проверяет на самом деле
Понимание трёх категорий, которые охватывает terraform validate, позволяет точно знать, что гарантирует успешная проверка и где эта гарантия заканчивается.
1. Корректность синтаксиса HCL
Первый проход разбирает каждый файл .tf на корректный синтаксис HCL2. Это выявляет незакрытые фигурные скобки, отсутствующие знаки равенства в присваивании атрибутов, недопустимые определения блоков, неправильное использование синтаксиса heredoc и любые другие конструкции, не являющиеся корректным HCL. Файл, не прошедший эту проверку, Terraform вообще не сможет прочитать — plan и apply тоже завершатся ошибкой. Validate сообщает об этих ошибках сразу, указывая путь к файлу и номер строки.
2. Соответствие схеме провайдера
После разбора validate проверяет каждый блок ресурса, блок источника данных и конфигурацию провайдера по схеме соответствующего плагина. Схемы определяют, какие аргументы допустимы, какие обязательны, а какие опциональны, и какой тип ожидается у каждого аргумента (string, number, bool, list, map, object). Validate выявляет аргумент, которого не существует для данного типа ресурса, аргумент с неверным типом (например, строку там, где ожидается число) и полностью отсутствующий обязательный аргумент.
Tip
3. Корректность внутренних ссылок
Третья категория — проверка перекрёстных ссылок внутри конфигурации. Конфигурации Terraform регулярно ссылаются по имени на другие ресурсы, переменные, local, выходы модулей и источники данных. Validate проверяет, что каждая ссылка (например var.region, local.common_tags, aws_vpc.main.id, module.networking.subnet_ids) указывает на что-то, действительно объявленное где-то в конфигурации. Необъявленная переменная, опечатка в ссылке на ресурс или отсутствующий выход модуля будут выявлены здесь.
| Категория проверки | Пример ошибки | Нужен init? |
|---|---|---|
| Ошибка разбора HCL | Незакрытая скобка в строке 14 | Нет |
| Неизвестный аргумент | "region" не является допустимым аргументом для aws_s3_bucket | Да |
| Неверный тип аргумента | Неподходящее значение атрибута — ожидается число | Да |
| Отсутствует обязательный аргумент | Аргумент "bucket" обязателен | Да |
| Необъявленная переменная | Управляемый ресурс может ссылаться только на объявленные переменные | Нет |
| Ссылка на необъявленный ресурс | Ссылка на необъявленный ресурс "aws_vpc.typo" | Нет |
| Отсутствует вход модуля | Аргумент "vpc_id" обязателен для module.network | Да |
Что terraform validate не проверяет
Границы terraform validate так же важны, как и его охват. Многие разработчики узнают об этих ограничениях, когда прошедшая проверку конфигурация даёт сбой во время применения. Каждая из этих категорий требует terraform plan, интеграционных тестов или инструментов политик вроде tflint или Checkov.
Реальные значения аргументов ресурсов
Validate проверяет, что аргумент существует и имеет правильный тип, но не может проверить, допустимо ли значение в реальном мире. У ресурса aws_instance аргумент ami может быть строкой (тип корректен), однако validate не может знать, существует ли конкретный AMI ID в вашем аккаунте или регионе AWS. Недопустимый AMI, несуществующий ID группы безопасности или неверное имя зоны доступности пройдут validate и дадут сбой только на этапе plan или apply.
Файл состояния и существующая инфраструктура
Validate никогда не читает ваш файл состояния Terraform. Он не может обнаружить, что описываемый ресурс конфликтует с уже существующим, что ресурс был удалён вне Terraform (расхождение состояния) или что планируемое изменение нарушает ограничение, которое можно оценить только по текущей реальной инфраструктуре. Всё это вопросы этапов plan и apply.
Динамические выражения, зависящие от источников данных
Выражения count, for_each и условные выражения — корректный HCL, и validate разбирает их без проблем. Но если их значения зависят от источника данных (например for_each = toset(data.aws_availability_zones.available.names)), выражение нельзя полностью вычислить во время проверки, потому что источник данных ещё не запрошен. Validate подтверждает корректность синтаксиса выражения, но не может подтвердить результат во время выполнения.
Аутентификация и права провайдера
Validate не делает ни одного вызова API. Он не обнаружит, что ваши учётные данные AWS истекли, что у сервисного аккаунта нет нужных прав IAM или что конфигурация провайдера указывает на неверный регион или проект. Все ошибки аутентификации проявляются только на этапе plan или apply, когда клиент провайдера действительно инициализируется и выполняются вызовы.
Warning
Политики безопасности и правила соответствия
Validate не имеет представления о политиках безопасности. Бакет S3, настроенный как публичный, инстанс EC2 без шифрования или группа безопасности с входящим правилом 0.0.0.0/0 на порт 22 пройдут validate без единого предупреждения. Для проверок безопасности и соответствия нужны специализированные инструменты политик: Checkov, tfsec или HashiCorp Sentinel.
terraform validate против terraform plan
Самый частый источник путаницы вокруг terraform validate — чем он отличается от terraform plan. Они существенно пересекаются, но работают на разных уровнях, и оба нужны для полноценного процесса перед применением.
terraform validate проверяет, является ли конфигурация синтаксически корректной и внутренне согласованной, независимо от переданных переменных или существующего состояния.
Где они пересекаются
Обе команды разбирают ваши файлы HCL и ищут ошибки синтаксиса. Обе проверяют схемы провайдеров, когда плагины доступны. Обе проверяют внутренние ссылки. Ошибку конфигурации, которую найдёт terraform validate, найдёт и terraform plan — validate просто быстрее и не требует облачных учётных данных или backend состояния.
Где plan идёт дальше
terraform plan инициализирует клиентов провайдеров, проходит аутентификацию в облачных API, читает текущее состояние и запрашивает источники данных. Это позволяет ему выявлять то, что не может validate: значение аргумента, которое API провайдера отклоняет, запрос к источнику данных с неожиданным результатом, ошибки квот или лимитов запросов и конфликты между предлагаемой конфигурацией и существующей инфраструктурой, отслеживаемой в состоянии.
| Возможность | terraform validate | terraform plan |
|---|---|---|
| Проверка синтаксиса HCL | ✓ Да | ✓ Да |
| Проверка схемы провайдера | ✓ Да (после init) | ✓ Да |
| Проверка перекрёстных ссылок | ✓ Да | ✓ Да |
| Проверка реальных значений ресурсов | ✗ Нет | ✓ Да (через API) |
| Чтение файла состояния | ✗ Нет | ✓ Да |
| Запрос к источникам данных | ✗ Нет | ✓ Да |
| Проверка аутентификации и прав | ✗ Нет | ✓ Да |
| Проверка политик безопасности | ✗ Нет | ✗ Нет (нужны tfsec/Checkov) |
| Требует облачных учётных данных | ✗ Нет | ✓ Да |
| Типичное время работы | < 2 с | от 5 с до нескольких минут |
Note
Как запустить terraform validate
Запустить terraform validate просто, но шаги вокруг него важны, чтобы получить от команды максимум пользы.
Выполните terraform init, чтобы скачать провайдеров
В рабочем каталоге Terraform выполните terraform init. Он скачивает плагины провайдеров, указанные в блоке required_providers, и сохраняет их в подкаталоге .terraform. Без init validate пропускает проверки схемы провайдеров и выполняет только разбор HCL и проверку ссылок. Используйте terraform init -backend=false в CI, чтобы пропустить настройку удалённого состояния, когда учётных данных нет.
Выполните terraform validate
Запустите terraform validate в том же каталоге. Команда завершается с кодом 0 (успех) или 1 (ошибка). При успехе выводится «Success! The configuration is valid.». При ошибке выводится каждое сообщение с путём к файлу, номером строки и столбца и описанием. Для структурированного вывода в скриптах CI используйте terraform validate -json.
# Базовая проверка
terraform validate
# Вывод JSON для разбора в CI
terraform validate -json
# Пример структуры вывода JSON
{
"valid": false,
"error_count": 2,
"diagnostics": [
{
"severity": "error",
"summary": "Unsupported argument",
"detail": "An argument named 'regoin' is not expected here. Did you mean 'region'?",
"range": {
"filename": "main.tf",
"start": { "line": 8, "column": 3 }
}
}
]
}Разберите и исправьте найденные ошибки
Каждая диагностика содержит путь к файлу и номер строки. Откройте указанный файл и посмотрите на отмеченную строку и 3–5 строк выше: ошибки HCL иногда появляются чуть позже фактической ошибки. Частые исправления включают корректировку имён аргументов (опечатки встречаются чаще всего), добавление пропущенного обязательного аргумента, исправление несоответствия типов (взять в кавычки число, которое должно быть без них) или объявление переменной, на которую есть ссылка, но которая не определена.
Продолжите с terraform plan
Когда validate пройдёт без ошибок, запустите terraform plan в среде с корректными учётными данными. Это второй фильтр, который выявляет проблемы времени выполнения, невидимые для validate: недопустимые значения ресурсов, ошибки прав и конфликты с состоянием инфраструктуры. Вместе две команды покрывают всю поверхность проверки перед применением.
Форматтер HCL
Нормализуйте отступы HCL, интервалы между блоками и выравнивание атрибутов в файлах Terraform перед запуском validate — прямо в браузере, без регистрации.
terraform validate в CI/CD
terraform validate отлично подходит для конвейеров CI, потому что не требует облачных учётных данных, выполняется за секунды и выявляет большинство ошибок автора до того, как они израсходуют запуск plan или дойдут до ревью кода. Стандартный приём — запускать его в каждом pull request, изменяющем файлы .tf.
Пример для GitHub Actions
Приведённый ниже рабочий процесс устанавливает Terraform, запускает init с -backend=false, чтобы не нужны были учётные данные состояния, и запускает validate. Если validate не проходит, рабочий процесс завершается с ненулевым кодом и блокирует слияние pull request.
name: Terraform Validate
on:
pull_request:
paths:
- '**.tf'
- '**.tfvars'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: '1.8.0'
- name: Terraform Init (no backend)
run: terraform init -backend=false
- name: Terraform Validate
run: terraform validate -json | tee validate-output.json
# Exit code 1 on any error - fails the workflow automaticallyTip
Сочетание validate и tflint
tflint — линтер, который выявляет проблемы, пропускаемые terraform validate: проверки правил конкретных провайдеров (например, недопустимые типы инстансов AWS), неиспользуемые объявления и собственные правила политик. Запуск tflint после validate в том же задании CI даёт более широкое покрытие статического анализа. У tflint есть плагины правил для AWS, Azure и GCP, которые сверяют значения аргументов с известными допустимыми вариантами и находят ошибки, недоступные общей проверке схемы в validate.
- terraform fmt -check — проверяет, что код соответствует стилевым соглашениям Terraform (сбой, если какой-то файл нужно переформатировать)
- terraform validate — проверяет синтаксис, соответствие схеме и внутренние ссылки
- tflint — правила конкретных провайдеров, поиск неиспользуемых переменных, применение собственных политик
- Checkov или tfsec — сканирование политик безопасности и соответствия
- terraform plan — проверка во время выполнения в среде staging с реальными учётными данными
Проверка соглашений об именовании ресурсов Terraform
Проверяйте имена ресурсов, модулей, переменных и выходов Terraform на единообразие стиля и соответствие политикам — полностью в браузере.
Лучшие практики полной проверки
terraform validate — это фундамент, а не потолок. Зрелый рабочий процесс Terraform сочетает несколько техник проверки, чтобы выявлять разные классы ошибок на нужном этапе цикла разработки.
Форматируйте до проверки
Запускайте terraform fmt перед validate в каждом процессе — локально и в CI. Каноническое форматирование HCL не просто вопрос стиля: оно предотвращает случаи, когда непоследовательные отступы или размещение комментариев скрывают реальные ошибки в выводе разбора. Форматтер HCL от Aback Tools выполняет ту же нормализацию в браузере без необходимости устанавливать Terraform — удобно для быстрых ревью или правок на машинах, где нельзя запустить terraform fmt.
В CI всегда делайте init перед validate
Запуск validate без init даёт лишь частичный анализ: разбор HCL и проверку ссылок, но без проверки схемы провайдеров. Пропуск проверок схемы означает, что вы можете слить конфигурацию с опечаткой в имени аргумента или с неверным типом, переданным атрибуту ресурса. Несколько дополнительных секунд, которые init -backend=false добавляет к заданию CI, стоят такого покрытия.
Используйте -json для структурированного вывода в CI
Стандартный человекочитаемый вывод validate удобен для локальной отладки, но в автоматизированных конвейерах вывод JSON гораздо полезнее. С -json вы можете разбирать массив diagnostics, извлекать пути к файлам и номера строк, аннотировать диффы pull request встроенными комментариями об ошибках через API GitHub Checks или передавать ошибки в собственное уведомление Slack. Сначала смотрите на булево valid: если оно true, массив diagnostics всё равно может содержать предупреждения, которые стоит показать.
Проверяйте все модули независимо
terraform validate в корневом модуле проверяет и вызываемые локальные модули, но удалённые модули проверяются только после их скачивания командой init. Для репозиториев модулей запускайте validate отдельно в каждом каталоге модуля во время разработки. Так ошибки схемы в самом модуле всплывают до того, как потребители начнут его использовать.
Warning
Держите файлы .tf отформатированными перед коммитом
Используйте pre-commit hook, который запускает terraform fmt -check и завершается ошибкой, если какой-то файл .tf не в каноническом формате. Это сохраняет согласованность всей кодовой базы, исключает чисто стилевые различия в ревью и делает вывод validate легче для чтения благодаря чистой структуре кода. Удаляйте комментарии разработчика из продакшн-конфигураций с помощью Удаления комментариев Terraform HCL, чтобы закоммиченные файлы оставались чистыми и читаемыми.
Key takeaways
- terraform validate проверяет синтаксис HCL, соответствие схеме провайдера и внутренние перекрёстные ссылки — он не делает вызовов API и не требует облачных учётных данных.
- Перед validate нужно выполнить terraform init, чтобы включить проверки схемы провайдеров; без этого validate пропускает проверку аргументов ресурсов.
- Validate не может обнаружить недопустимые значения аргументов, расхождение состояния, отсутствующие права и нарушения политик безопасности — для этого нужны terraform plan и специализированные инструменты политик.
- Флаг -json выводит структурированные диагностики (valid, error_count, diagnostics[]), идеальные для разбора в CI, встроенных аннотаций в PR и собственных конвейеров отчётности.
- Правильный конвейер CI: terraform fmt -check → terraform init -backend=false → terraform validate → tflint → terraform plan (в staging с учётными данными).
- Используйте форматтер HCL и Проверку соглашений об именовании ресурсов Terraform для стилевой и именной гигиены перед проверкой.
- Успешная проверка terraform validate не означает, что конфигурация готова к применению — она означает, что конфигурация достаточно корректна синтаксически и структурно, чтобы перейти к plan.