linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-beginner-11-fmt-validate-console

lesson ── terraform-beginner ── ~12 мин ── 5 шагов

Гигиена HCL: fmt, validate, console

Десять предыдущих уроков были про что Terraform делает. Этот урок, про три команды, которые ты будешь запускать каждый день и которые предотвращают 80% позора на код-ревью: fmt, validate, console.

Это не «бонус», это базовая гигиена. Без них HCL превращается в спагетти, опечатки в именах атрибутов всплывают в plan или apply (а без validate в pre-commit, иногда и того позже), а сложные выражения дебажатся методом «правлю → plan → читаю → правлю».

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Создай специально кривой HCL

    В ~/tf-hygiene создай main.tf со специально плохим форматированием:

    hcl
    resource "aws_s3_bucket"   "demo" {
     bucket="linuxlab-hygiene-${random_id.suffix.hex}"
      tags={
      Owner="student"
        Project    ="hygiene-demo"
     }
    }
    resource "random_id" "suffix" {
     byte_length=4
    }

    Кривые отступы, отсутствующие пробелы вокруг =, разнобой. Это типичная картина после слияния PR от трёх разработчиков с разными настройками IDE.

    Не запускай terraform пока, сначала посмотрим как fmt с этим разберётся.

    подсказка

    Можно скопировать целиком через `cat > main.tf <<EOF ... EOF`. Не правь отступы: пусть они будут кривыми.

    ✓ Файл сохранён. Теперь приведём его в порядок.

  2. 02

    terraform fmt: починить за секунду

    Запусти:

    bash
    cd /home/student/tf-hygiene
    terraform fmt

    В выводе, main.tf. Это значит файл был неотформатирован, теперь исправлен.

    Открой файл и посмотри:

    bash
    cat main.tf

    Теперь там:

    • Отступы по 2 пробела.
    • Пробелы вокруг =.
    • Значения Owner и Project выровнены по =.
    • Никаких лишних пустых строк.

    Это тот же код, не другой. Только стиль. terraform plan выдал бы одинаковый результат и до, и после fmt.

    Привычка: fmt после каждого редактирования. Или поставь в IDE на save. См. tf-fmt.

    подсказка

    Если fmt ничего не вывел, значит уже отформатирован. Скопируй файл с кривыми отступами заново.

    ✓ После fmt -check проверка чистая: стиль каноничный.

  3. 03

    terraform validate: проверка без облака

    Подкинем в HCL опечатку. Открой main.tf и поменяй bucket на bucket_name:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket_name = "linuxlab-hygiene-${random_id.suffix.hex}"
      # ^^^^^^^^^^^ намеренная опечатка
      tags = {
        Owner   = "student"
        Project = "hygiene-demo"
      }
    }

    Запусти init + validate:

    bash
    terraform init -backend=false -input=false
    terraform validate

    Получишь:

    Error: Unsupported argument
      on main.tf line 2, in resource "aws_s3_bucket" "demo":
       2:   bucket_name = "linuxlab-hygiene-..."
    An argument named "bucket_name" is not expected here.
    Did you mean "bucket"?

    Заметь Did you mean "bucket"?, это автоматическая подсказка по похожим именам. Спасает на опечатках.

    Validate не ходит в облако. Это секунда дебага вместо минуты apply → Error from AWS → разбор.

    подсказка

    Если validate говорит 'no provider': забыл `terraform init -backend=false`.

    ✓ validate поймал опечатку. Теперь починим и проверим что стало чисто.

  4. 04

    Поправь опечатку и убедись что чисто

    Верни bucket_name → bucket:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-hygiene-${random_id.suffix.hex}"
      tags = {
        Owner   = "student"
        Project = "hygiene-demo"
      }
    }
    bash
    terraform fmt
    terraform validate

    Validate должен сказать:

    Success! The configuration is valid.

    Это правильный workflow: пиши HCL → fmt → validate. Только после этого имеет смысл делать plan/apply.

    В CI этот же workflow автоматизирован через pre-commit hooks и сборку линтеров. См. tf-validate.

    подсказка

    Если validate всё ещё ругается: поищи `bucket_name` в файле (`grep -n bucket_name main.tf`), мог остаться где-то.

    ✓ HCL валиден. Можно переходить к plan/apply.

    То же самое на OpenTofu

    OpenTofu держит CLI и state совместимыми с Terraform по командам этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе сделай backup state и прогон на feature-branch - расхождения концентрируются в новых фичах (variables в backend, state-encryption, OCI registry-backed модули). См. tf-opentofu-parity для полной матрицы.

    • → OpenTofu parity
  5. 05

    terraform console. REPL для выражений

    Перед тем как воткнуть сложное выражение в HCL, проверь его в console. Сначала применим конфигурацию чтобы был state:

    bash
    terraform apply -auto-approve

    Теперь:

    bash
    terraform console

    Появится >. Попробуй:

    > 1 + 2 * 3
    7
    > upper("terraform")
    "TERRAFORM"
    > length(aws_s3_bucket.demo.tags)
    2
    > aws_s3_bucket.demo.arn
    "arn:aws:s3:::linuxlab-hygiene-..."
    > [for k, v in aws_s3_bucket.demo.tags : "${k}=${v}"]
    [
      "Owner=student",
      "Project=hygiene-demo",
    ]

    Выйти, exit или Ctrl+D.

    Это главный use case console: проверить выражение до того как воткнуть его в HCL. Сэкономит часы на этапе intermediate-трека (модули, dynamic blocks, сложные locals). См. tf-console.

    подсказка

    Если console падает с 'configuration is invalid': сначала validate, потом console.

    ✓ Console работает, видит state, считает выражения. Это твой главный инструмент дебага HCL.

    Что делает type() и зачем

    В console есть спецоператор type(...), печатает выведенный тип выражения:

    > type(var.region)
    string
    > type(aws_s3_bucket.demo.tags)
    map of string
    > type([1, 2, 3])
    tuple([number, number, number])

    Это спасает в двух местах:

    • При написании модуля (input variable принимает list или set?).
    • При for_each (set or map требуется, не list).

    Часто на код-ревью «почему этот тип, а не другой» решается одной строкой в console. См. hcl-types про различия типов.

    • → Типы данных HCL
    • → terraform console целиком

Что ты узнал

Три инструмента, три привычки. fmt после каждого редактирования. validate перед каждым plan. console для проверки локалов и выражений до того как воткнуть их в HCL.

команды

  • terraform fmt -recursiveформатирование, включая модули
  • terraform validateпроверка HCL без обращения в облако
  • terraform consoleREPL для выражений и проверки state
  • echo 'type(var.X)' | terraform consoleне-интерактивная проверка типа

концепции

  • · fmt не меняет смысл, только стиль: запускать всегда
  • · validate ловит синтаксис и неизвестные аргументы, не ловит логику
  • · console: самый недооценённый инструмент Terraform

← предыдущий

Drift detection, scheduled plan и алертинг

следующий →

Утилитарные провайдеры: random, time, archive, external

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки