Что делает fmt
terraform fmt, это gofmt для HCL. Он не меняет смысл вашего кода,
только приводит его к одному стилю: одинаковые отступы (два пробела),
выровненные = в блоках аргументов, схлопнутые пустые строки,
одинаковые кавычки.
Цель, снять с код-ревью обсуждения «здесь четыре пробела, там два» и держать diff'ы в PR про логику, а не про пробелы.
Базовое использование
Без флагов, форматирует все .tf и .tfvars файлы в текущей папке
и пишет изменения на диск:
cd ~/myproject
terraform fmt
В выводе, список изменённых файлов:
main.tf
variables.tf
Если ничего не выведено, всё уже было отформатировано.
Рекурсивно по всей папке
По умолчанию fmt смотрит только в текущую директорию. Чтобы пройтись
по всем подпапкам:
terraform fmt -recursive
Это нужно в репозиториях с модулями (modules/vpc/, modules/alb/): без -recursive они не отформатируются.
Что fmt делает с HCL
До:
resource "aws_s3_bucket" "demo" {bucket="my-bucket"
tags={Owner="student"
Env ="dev"
}
}
После terraform fmt:
resource "aws_s3_bucket" "demo" {bucket = "my-bucket"
tags = {Owner = "student"
Env = "dev"
}
}
Заметьте: Owner и Env теперь выровнены по =. Это автоматика, не
ручной труд.
Режимы для CI
Локально вы хотите чтобы fmt исправлял файлы. В CI, чтобы он
проваливал сборку, если кто-то закоммитил неформатированный код.
# упасть с ненулевым exit code, если что-то не отформатировано
terraform fmt -check -recursive
# то же самое + показать diff что именно не так
terraform fmt -check -diff -recursive
Флаги:
-check, не писать на диск, exit 0 = всё ок, exit 3 = есть неотформатированные.-diff, показать построчный diff.-write=false, синоним «не писать», обычно его не используют отдельно.
Pre-commit hook
Самое практичное применение, поставить fmt в pre-commit, чтобы не
пропускать unformatted код в git вообще:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.88.0
hooks:
- id: terraform_fmt
Тогда git commit сам отформатирует tf-файлы перед коммитом. Если в
репозиторий попал кривой стиль, это была сознательная попытка обойти
hook, не «забыли запустить fmt».
Что fmt НЕ делает
- Не проверяет синтаксис. Битый HCL fmt не починит. Для синтаксиса есть tf-validate.
- Не переписывает имена.
Resourceвместоresource, это ошибка, не «плохой стиль». Поймает её validate. - Не сортирует аргументы по алфавиту. Порядок аргументов внутри блока сохраняется.
- Не трогает комментарии. Если в коде есть
# Замечание здесь, оно останется на месте. - Не работает с .tf.json. Только с HCL.
Подводные камни
fmtпишет на диск по умолчанию. Если коллега в IDE открыл файл и не сохранил, а вы запустилиfmt, его изменения могут потеряться. В корпоративном setup лучше через IDE-интеграцию (Terraform extension VS Code/JetBrains сам зовёт fmt).fmt -recursiveобходит.terraform/тоже. Если хочется игнорить,.terraform/обычно в.gitignore, и проблем нет, но fmt всё равно туда заглянет.- Версия terraform имеет значение. Между минорными версиями
правила форматирования иногда меняются (например, в 1.9 добавили
выравнивание comments). Команда должна быть на одной версии, иначе
PR с «fmt-only» правками будут плодиться. Решается через
.terraform-version(для tfenv) или CI с зафиксированной версией. - Не запускайте
fmtна CI без-check. Иначе CI сам исправит файлы и закоммитит, но кто хозяин коммита, непонятно. Локально исправлять, в CI только проверять.