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-production-02-pre-commit

lesson ── terraform-production ── ~14 мин ── 6 шагов

pre-commit hooks для Terraform

pre-commit, Python-фреймворк для git-hook'ов. Объявляешь набор проверок в .pre-commit-config.yaml, запускаешь pre-commit install, и теперь каждый git commit гоняет fmt/validate/tflint перед тем, как пустить изменения в репо. Тот же конфиг, в CI: pre-commit run --all-files.

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

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

запустить sandbox →

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

Шаги

  1. 01

    Положи рабочий HCL в git-repo

    bash
    cd /home/student/tf-precommit
    git init -q
    git config user.email "student@linuxlab.local"
    git config user.name "student"
    cat > main.tf <<'EOF'
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-precommit-demo"
      tags = {
        Owner = "student"
      }
    }
    EOF
    terraform fmt
    git add .
    git commit -q -m "init: clean hcl"
    git log --oneline

    В репо один чистый коммит, baseline.

    ✓ Git инициализирован, чистый baseline закоммичен.

  2. 02

    Создай .pre-commit-config.yaml

    bash
    cat > .pre-commit-config.yaml <<'EOF'
    repos:
      - repo: https://github.com/antonbabenko/pre-commit-terraform
        rev: v1.95.0
        hooks:
          - id: terraform_fmt
          - id: terraform_validate
          - id: terraform_tflint
            args:
              - --args=--init
      - repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v5.0.0
        hooks:
          - id: end-of-file-fixer
          - id: trailing-whitespace
    EOF

    Заметь: hook ID, terraform_fmt, не просто fmt. Это имя из репо antonbabenko/pre-commit-terraform, де-факто стандарт для Terraform.

    Установи hook'и в git:

    bash
    pre-commit install
    ls .git/hooks/pre-commit

    Файл .git/hooks/pre-commit появился, это wrapper, который при каждом commit запустит pre-commit.

    ✓ Hook установлен, теперь git commit пройдёт через pre-commit.

  3. 03

    Hook ловит грязный коммит

    Положи нарочно нечистый файл:

    bash
    cat > badly.tf <<'EOF'
    resource "aws_s3_bucket"   "another"  {
    bucket="bad-format"
    }
    EOF
    git add badly.tf
    set +e
    git commit -m "feat: add another bucket"
    echo "exit: $?"
    set -e

    Commit упал, потому что terraform_fmt нашёл проблему. Pre-commit сам сделал auto-fix, но файлы остались unstaged.

    Проверь:

    bash
    git status
    cat badly.tf

    badly.tf теперь отформатирован, но git его уже видит как «modified», pre-commit изменил после git add.

    ✓ Hook auto-fix'нул формат. Без него commit бы прошёл с грязным HCL.

  4. 04

    Re-stage и завершить commit

    bash
    git add badly.tf
    git commit -m "feat: add another bucket"
    git log --oneline

    Теперь pre-commit прошёл, файл уже чист. Commit принят.

    В реальной работе цикл такой: commit → hook fix → re-add → commit. Чем чище код dev писал, тем реже re-add.

    ✓ Чистый коммит прошёл pre-commit gate.

  5. 05

    validate-hook блокирует битый HCL

    Положи ссылку на несуществующий ресурс:

    bash
    cat >> main.tf <<'EOF'
    output "broken" {
      value = aws_s3_bucket.does_not_exist.arn
    }
    EOF
    git add main.tf
    set +e
    git commit -m "feat: broken reference"
    code=$?
    set -e
    echo "exit: $code"

    Должно упасть на terraform_validate, ссылка на несуществующий ресурс. Это не format-issue, который auto-fix; это semantic-issue, требует ручного исправления.

    Откати:

    bash
    git restore --staged main.tf
    sed -i '/output "broken"/,/^}$/d' main.tf
    cat main.tf

    ✓ validate отбил битый HCL. Без pre-commit это бы дошло до plan'а в CI.

    То же самое на 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
  6. 06

    pre-commit run --all-files в CI

    Локально hook'и срабатывают на ИЗМЕНЁННЫЕ файлы. В CI нужно прогнать всё, старые файлы тоже могут не соответствовать политике (особенно сразу после adoption pre-commit'а в legacy-репо).

    bash
    pre-commit run --all-files
    echo "exit: $?"

    Должно показать pass'ы. Если бы кто-то закоммитил bypass'нув hook (--no-verify), --all-files это поймал бы.

    Это финальный CI-шаг: pre-commit run --all-files, exit 1 на любую проблему.

    ✓ pre-commit gate работает. Дальше, функциональные тесты.

    Hook'и которые не вошли в базовый набор

    Что ещё есть в antonbabenko/pre-commit-terraform и зачем:

    • terraform_docs, автогенерация README.md с inputs/outputs. Удобно для модулей; запускается в CI с --args=--output-file, чтобы README обновлялся при изменении variables.
    • terraform_checkov, checkov в pre-commit. Медленно; обычно только в CI.
    • terraform_trivy, то же, что checkov, но trivy. Выбор один из двух.
    • terraform_tfsec, устаревший, см. tf-trivy-tfsec.
    • terragrunt_fmt / terragrunt_validate, если у тебя terragrunt-обвязка.
    • infracost_breakdown, оценка стоимости. Требует API-токен.

    Правило: чем дольше hook, тем меньше его в local-precommit, и больше в CI. Локально хочется проверки за <5 секунд.

    • → pre-commit и CI
    • → Checkov для security-scan

Что ты узнал

pre-commit подключается к git через pre-commit install, читает .pre-commit-config.yaml, гоняет hook'и при коммите. Hook'и под Terraform, антибабенко/pre-commit-terraform: terraform_fmt, terraform_validate, terraform_tflint, terraform_docs.

команды

  • pre-commit installподключить hook'и в .git/hooks. Один раз после clone.
  • pre-commit run --all-filesпрогнать всё репо. Использовать для bootstrap'а на старом проекте.
  • SKIP=terraform_fmt git commitпропустить один hook. Только осознанно.
  • pre-commit autoupdateподнять версии rev: в конфиге.

концепции

  • · terraform_fmt в локальном hook'е, с auto-fix; в CI, fmt -check
  • · pre-commit и CI используют один конфиг, нет drift'а между local и pipeline
  • · git commit --no-verify обходит всё. Лучше так не делать.

← предыдущий

Модуль из Terraform Registry

следующий →

Свой Terraform-provider, Go и Plugin Framework

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