terrafmt

August 3, 2026 ยท View on GitHub

GitHub release build test lint govulncheck CodeQL Go Version License

A tool for extracting and formatting Terraform configuration embedded in other files, primarily intended to help with provider development.

Install

Homebrew

brew install katbyte/tap/terrafmt

Pre-built binaries

Binaries for linux, macOS, windows, freebsd, openbsd, and solaris are attached to each release.

Go

go install github.com/katbyte/terrafmt@latest

Usage

Information about usage and options can be found by using the help command:

terrafmt help

terrafmt finds terraform blocks embedded in files, runs the equivalent of terraform fmt on them, and can display the difference or update them in place. It understands:

  • Markdown (.md, .markdown, and other non-go files): fenced code blocks opened with ```hcl, ```tf, or ```terraform
  • reStructuredText (.rst): .. code:: terraform directives (block indentation is preserved)
  • Go (.go): multiline string literals that look like terraform configuration, e.g. acceptance test configs returned by fmt.Sprintf

Extract Terraform Blocks

Use the blocks command to extract blocks from a file:

blocks

To output only the block content, separated by the null character, use --zero-terminated/-z.

To output the blocks as JSON, use --json/-j:

blocks -j

Go format verbs (%s, %d, %[1]q, ...) can be escaped in the output blocks with --fmtcompat/-f.

Show What Format Would Do

Use the diff command to see what would be formatted (files can also be piped in on stdin):

diff

For go files containing format verbs use the -f switch:

diff -f

Format Files

Use the fmt command to format blocks in place. It accepts a single file, stdin, or a directory to walk โ€” combine with --pattern/-p to filter by file name:

fmt

terrafmt fmt ./website --pattern '*.markdown'
terrafmt fmt ./internal --pattern '*_test.go' -f

Exit codes

To help usage of terrafmt in workflows, some commands return actionable exit codes.

If a terraform parsing error is encountered in a block, the exit code is 2.

If the diff command with the --check flag enabled encounters a formatting difference, it will return 4. If a file contains both blocks with parsing errors and a formatting difference, the codes combine to 6. These can be tested using bitwise checks.

Otherwise, terrafmt returns 1 on an error.

Environment variables & config file

Most flags can also be set with an environment variable, or persisted in a .terrafmt config file in the current directory or your home directory. Flags take precedence over environment variables, which take precedence over the config file.

FlagEnvironment variable
--fmtcompat/-fTERRAFMT_FMTCOMPAT
--check/-cTERRAFMT_CHECK
--verbose/-vTERRAFMT_VERBOSE
--quiet/-qTERRAFMT_QUIET
--uncoloured/-uTERRAFMT_UNCOLOURED
--pattern/-pTERRAFMT_PATTERN
--fix-finish-linesTERRAFMT_FIX_FINISH_LINES

The config file uses key=value lines with the flag names as keys, for example:

fmtcompat=true
pattern=*.markdown

Development

This project uses Go Modules with a vendored vendor/ directory.

make help       # list all targets
make build      # build the binary
make test       # run the tests (with -race)
make lint       # run golangci-lint
make lint-fix   # run golangci-lint and apply autofixes
make fmt        # gofmt/gofumpt/goimports the source
make depscheck  # verify go.mod/go.sum/vendor are consistent
make check-all  # build + test + lint + depscheck

When updating dependencies, re-vendor:

go get <module>
go mod tidy
go mod vendor

Releasing

Releases are cut by pushing a semver tag; CI (goreleaser) builds the binaries, publishes the GitHub release, and updates the homebrew tap formula:

git tag v0.6.0
git push origin v0.6.0