Перейти к содержимому
Aback Tools Logo

Что на самом деле проверяет terraform validate?

terraform validate проверяет синтаксис HCL, соответствие схеме провайдера и внутренние ссылки, но не значения ресурсов, состояние и права доступа. Подробный разбор возможностей.

DH
Tutorials & How-Tos12 мин чтения2,700 слов

terraform validate — одна из первых команд, которые осваивают пользователи Terraform, и одновременно одна из самых непонятых. Он не подключается ни к одному облачному провайдеру. Он не проверяет, допустимы ли значения ваших ресурсов в реальном мире. Он не смотрит в файл состояния. То, что он делает, быстро, безопасно и необходимо, но понимание того, где именно он останавливается, отличает надёжный конвейер CI от ложного чувства безопасности перед terraform apply.

0Вызовов APIполностью офлайн статический анализ
3Категории провероксинтаксис, схема, ссылки
< 2 сТипичное время работына большинстве реальных конфигураций

Что такое terraform validate

terraform validate — встроенная подкоманда Terraform, выполняющая статический анализ ваших файлов конфигурации. Она читает каждый файл .tf и .tfvars в текущем рабочем каталоге (и рекурсивно все локальные модули), разбирает их и проверяет, является ли конфигурация внутренне согласованной и структурно корректной.

Статический анализ, а не выполнение

Ключевая особенность terraform validate в том, что он полностью статичен. Сетевые подключения не выполняются, API провайдеров не вызываются, файл состояния не читается. Проверка целиком происходит в памяти на машине, где запущена команда. Поэтому её безопасно запускать в любой среде, включая CI-раннеры без облачных учётных данных, и она завершается менее чем за две секунды на большинстве реальных конфигураций.

Это отличается от terraform plan, который выполняет те же статические проверки, а затем подключается к API провайдеров, чтобы вычислить разницу с реальной инфраструктурой. Validate — лёгкий первый фильтр; plan — исчерпывающий фильтр перед применением. Запуск обоих по очереди даёт самую широкую проверку перед тем, как вы согласитесь на изменение инфраструктуры.

Note

terraform validate значительно улучшился в Terraform 0.12, когда языком конфигурации стал HCL2. До 0.12 проверка была поверхностной, и многие структурные ошибки всплывали только на этапе plan. Начиная с 0.12 у validate есть полноценная система типов и знание схемы, что делает его существенно полезнее как самостоятельная проверка.

Три режима работы

  • Обычный режим — запускается после 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

Чтобы validate мог проверять схемы провайдеров, нужно выполнить terraform init в рабочем каталоге. Init скачивает плагины провайдеров и сохраняет их в каталоге .terraform. Без этого validate не с чем сравнивать схему и пропускает проверку на уровне ресурсов. Стандартный конвейер CI всегда такой: init → validate → plan.

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

Успешная проверка terraform validate не означает, что конфигурацию можно применять. Она означает, что конфигурация синтаксически корректна и валидна по схеме. Всегда после validate запускайте terraform plan — по возможности в среде staging — прежде чем выполнять terraform apply в продакшене.

Политики безопасности и правила соответствия

Validate не имеет представления о политиках безопасности. Бакет S3, настроенный как публичный, инстанс EC2 без шифрования или группа безопасности с входящим правилом 0.0.0.0/0 на порт 22 пройдут validate без единого предупреждения. Для проверок безопасности и соответствия нужны специализированные инструменты политик: Checkov, tfsec или HashiCorp Sentinel.

terraform validate против terraform plan

Самый частый источник путаницы вокруг terraform validate — чем он отличается от terraform plan. Они существенно пересекаются, но работают на разных уровнях, и оба нужны для полноценного процесса перед применением.

terraform validate проверяет, является ли конфигурация синтаксически корректной и внутренне согласованной, независимо от переданных переменных или существующего состояния.

- Документация HashiCorp Terraform

Где они пересекаются

Обе команды разбирают ваши файлы HCL и ищут ошибки синтаксиса. Обе проверяют схемы провайдеров, когда плагины доступны. Обе проверяют внутренние ссылки. Ошибку конфигурации, которую найдёт terraform validate, найдёт и terraform plan — validate просто быстрее и не требует облачных учётных данных или backend состояния.

Где plan идёт дальше

terraform plan инициализирует клиентов провайдеров, проходит аутентификацию в облачных API, читает текущее состояние и запрашивает источники данных. Это позволяет ему выявлять то, что не может validate: значение аргумента, которое API провайдера отклоняет, запрос к источнику данных с неожиданным результатом, ошибки квот или лимитов запросов и конфликты между предлагаемой конфигурацией и существующей инфраструктурой, отслеживаемой в состоянии.


Возможностьterraform validateterraform plan
Проверка синтаксиса HCL✓ Да✓ Да
Проверка схемы провайдера✓ Да (после init)✓ Да
Проверка перекрёстных ссылок✓ Да✓ Да
Проверка реальных значений ресурсов✗ Нет✓ Да (через API)
Чтение файла состояния✗ Нет✓ Да
Запрос к источникам данных✗ Нет✓ Да
Проверка аутентификации и прав✗ Нет✓ Да
Проверка политик безопасности✗ Нет✗ Нет (нужны tfsec/Checkov)
Требует облачных учётных данных✗ Нет✓ Да
Типичное время работы< 2 сот 5 с до нескольких минут

Note

В конвейерах CI validate и plan решают разные задачи. Запускайте validate на каждом коммите в pull request: это быстро, не требует учётных данных и рано выявляет большинство ошибок автора. Запускайте plan в отдельном задании с доступом к учётным данным staging — при слиянии или как шаг ручного подтверждения.

Как запустить terraform validate

Запустить terraform validate просто, но шаги вокруг него важны, чтобы получить от команды максимум пользы.

1

Выполните terraform init, чтобы скачать провайдеров

В рабочем каталоге Terraform выполните terraform init. Он скачивает плагины провайдеров, указанные в блоке required_providers, и сохраняет их в подкаталоге .terraform. Без init validate пропускает проверки схемы провайдеров и выполняет только разбор HCL и проверку ссылок. Используйте terraform init -backend=false в CI, чтобы пропустить настройку удалённого состояния, когда учётных данных нет.

2

Выполните terraform validate

Запустите terraform validate в том же каталоге. Команда завершается с кодом 0 (успех) или 1 (ошибка). При успехе выводится «Success! The configuration is valid.». При ошибке выводится каждое сообщение с путём к файлу, номером строки и столбца и описанием. Для структурированного вывода в скриптах CI используйте terraform validate -json.

terminal
bash
# Базовая проверка
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

Разберите и исправьте найденные ошибки

Каждая диагностика содержит путь к файлу и номер строки. Откройте указанный файл и посмотрите на отмеченную строку и 3–5 строк выше: ошибки HCL иногда появляются чуть позже фактической ошибки. Частые исправления включают корректировку имён аргументов (опечатки встречаются чаще всего), добавление пропущенного обязательного аргумента, исправление несоответствия типов (взять в кавычки число, которое должно быть без них) или объявление переменной, на которую есть ссылка, но которая не определена.

4

Продолжите с terraform plan

Когда validate пройдёт без ошибок, запустите terraform plan в среде с корректными учётными данными. Это второй фильтр, который выявляет проблемы времени выполнения, невидимые для validate: недопустимые значения ресурсов, ошибки прав и конфликты с состоянием инфраструктуры. Вместе две команды покрывают всю поверхность проверки перед применением.

Форматтер HCL

Нормализуйте отступы HCL, интервалы между блоками и выравнивание атрибутов в файлах Terraform перед запуском validate — прямо в браузере, без регистрации.

Open tool

terraform validate в CI/CD

terraform validate отлично подходит для конвейеров CI, потому что не требует облачных учётных данных, выполняется за секунды и выявляет большинство ошибок автора до того, как они израсходуют запуск plan или дойдут до ревью кода. Стандартный приём — запускать его в каждом pull request, изменяющем файлы .tf.

Пример для GitHub Actions

Приведённый ниже рабочий процесс устанавливает Terraform, запускает init с -backend=false, чтобы не нужны были учётные данные состояния, и запускает validate. Если validate не проходит, рабочий процесс завершается с ненулевым кодом и блокирует слияние pull request.

.github/workflows/terraform-validate.yml
yaml
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 automatically

Tip

Использование -backend=false означает, что terraform init скачивает плагины провайдеров, не пытаясь инициализировать удалённый backend состояния. Это правильный приём для CI-заданий pull request, которые не должны затрагивать общий файл состояния и не имеют учётных данных backend.

Сочетание 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 на единообразие стиля и соответствие политикам — полностью в браузере.

Open tool

Лучшие практики полной проверки

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

Распространённое заблуждение — что terraform validate покрывает безопасность. Это не так. Вполне корректная конфигурация Terraform может создать публично доступные бакеты хранилища, незашифрованные базы данных или чрезмерно широкие роли IAM. Всегда запускайте Checkov, tfsec или аналогичный сканер политик отдельным шагом после validate в конвейере CI.

Держите файлы .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.

Частые вопросы

terraform validate проверяет три вещи: корректность синтаксиса HCL (допустимые блоки, правильный синтаксис атрибутов, отсутствие ошибок разбора), соответствие схеме (распознаёт ли провайдер использованные атрибуты и заданы ли они совместимыми типами) и корректность внутренних ссылок (объявлены ли где-либо в конфигурации все переменные, local, выходы модулей и ссылки на ресурсы). Он не подключается ни к одному API провайдера, поэтому не может проверить, существует ли ресурс с такими аргументами на самом деле или может ли он быть создан.

Да, для полной проверки. terraform init скачивает плагины провайдеров и их определения схем; без них terraform validate не может проверить, допустимы ли использованные аргументы для данного типа ресурса. Начиная с Terraform 0.13, запуск validate без init даёт ошибку для конфигураций, ссылающихся на провайдеров. Если вы хотите полностью пропустить проверки схемы (например, при проверке только синтаксиса), примите это ограничение, но стандартный порядок — сначала init, затем validate.

terraform validate — это чисто статический этап анализа: он читает ваши файлы .tf, проверяет синтаксис и схему и завершается, не обращаясь ни к одному API провайдера. terraform plan выполняет те же проверки, а затем подключается к API провайдеров, чтобы определить, какие изменения действительно будут внесены. Plan выявляет то, что validate не видит: недопустимые значения аргументов (например, несуществующий регион), отсутствующие права, лимиты квот и расхождение состояния. Validate быстр и безопасен для CI; plan требует учётных данных и реального доступа к инфраструктуре.

Нет. terraform validate находит структурные ошибки и несоответствия схеме, но пропускает важный класс ошибок времени выполнения. Он не обнаружит недопустимый AMI ID в инстансе AWS, имя бакета GCS, нарушающее правила символов, или ресурс, конфликтующий с уже существующим в состоянии. Он также не проверяет логику выражений count и for_each, если они зависят от источников данных или удалённых значений. Воспринимайте validate как быстрый первый фильтр: необходимый, но недостаточный для полной уверенности перед применением.

Добавьте задание CI, которое запускает terraform init, а затем terraform validate. Используйте действие hashicorp/setup-terraform, чтобы установить нужную версию Terraform, затем выполните init с -backend=false, чтобы пропустить инициализацию удалённого состояния (она требует учётных данных), и следом validate. Шаг validate завершается с ненулевым кодом при любой ошибке, что приводит к сбою рабочего процесса и блокирует pull request. Этот приём выявляет ошибки синтаксиса HCL и схемы на каждом коммите без облачных учётных данных в среде CI.

Флаг -json заставляет terraform validate выводить структурированный объект JSON вместо человекочитаемого текста. Объект содержит булево поле valid (true или false), целое error_count и массив diagnostics. Каждая запись diagnostics включает severity (error или warning), краткое описание summary, строку detail и объект range с полями filename, начальная и конечная строка. Этот формат идеален для разбора в скриптах CI, интеграции с собственными панелями отчётов или передачи в расширения редакторов с встроенными аннотациями.

Да, частично. terraform validate проверяет, что блоки вызова модуля ссылаются на источник, существующий локально или разрешимый, что обязательные входные переменные модуля заданы и что типы, передаваемые во входы модуля, совместимы с объявлениями переменных внутри модуля. Удалённые модули не скачиваются во время проверки, если их уже не скачал terraform init. После init скачанный источник модуля доступен локально и может быть полностью проверен по схеме.

Полноценный рабочий процесс качества Terraform включает несколько инструментов. terraform validate покрывает синтаксис и схему. terraform plan покрывает поведение во время выполнения. tflint добавляет проверки правил конкретных провайдеров и собственные правила политик сверх того, что обеспечивает validate. Checkov и tfsec выполняют сканирование политик безопасности. Для форматирования HCL и согласованности стиля перед всем этим форматтер HCL от Aback Tools нормализует отступы и структуру блоков, а Проверка соглашений об именовании ресурсов Terraform проверяет имена по правилам вашей команды.

ShareXLinkedIn