Keep configurations clean and correct — auto-format with fmt, catch errors with validate, enforce best practices with TFLint, and assert behavior with native terraform test.
Why: consistent formatting removes pointless diffs and arguments. terraform fmt rewrites your files to the canonical style — indentation, alignment, spacing. Run it before every commit; -check (no writes) fails in CI if anything is unformatted, and -recursive covers subdirectories.
Reformat files in place
terraform fmtCI mode: fail if anything is not formatted (no changes made)
terraform fmt -check -recursiveWhy: terraform validate checks that your configuration is internally consistent — valid syntax, correct argument types, references that resolve — without touching any real infrastructure or needing credentials. It is fast and catches a whole class of mistakes before plan. Run init first so providers are available.
terraform initterraform validateWhy: validate checks correctness; a linter checks quality. TFLint flags deprecated syntax, unused declarations, provider-specific mistakes (an invalid instance type), and naming-convention breaks that Terraform itself accepts. It is the highest-value extra check — add it to CI. See https://github.com/terraform-linters/tflint.
Install once, then from your project:
tflint --init # download provider rule pluginstflint # lint the current configurationWhy: native terraform test (built in since 1.6) runs your configuration in a temporary state and asserts the results, so you can prove a module behaves before shipping it. Tests live in .tftest.hcl files: each run block applies (or plans) and checks assert conditions. This is how you unit-test modules.
# tests/note.tftest.hcl
run "writes_the_file" {
command = apply
variables {
name = "test"
message = "hi"
}
assert {
condition = output.path == "test.txt"
error_message = "module wrote the wrong filename"
}
}terraform test discovers every *.tftest.hcl file, runs each run block in order against a throwaway state, and tears everything down afterward — so tests never touch your real state. A non-zero exit on failure makes it CI-ready.
Run all *.tftest.hcl tests
terraform test