Terraform Tutorial — terraform fmt and validate
Two commands that every Terraform user should run constantly: terraform fmt for consistent formatting and terraform validate for catching errors early. Together, they keep your code clean and correct before you ever touch real infrastructure.
terraform fmt — Auto-Format Your Code
terraform fmt rewrites your .tf files to the canonical HCL style. It handles:
- Indentation: 2 spaces per level
- Alignment:
=signs aligned in argument blocks - Spacing: Consistent blank lines between blocks
- Quotes: Normalized quoting style
Before Formatting
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags={
Name="example"
Environment = "dev"
}
}
After terraform fmt
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
tags = {
Name = "example"
Environment = "dev"
}
}
Running fmt
# Format all .tf files in current directory
$ terraform fmt
# Format recursively (all subdirectories)
$ terraform fmt -recursive
# Check if files are formatted (exit code 1 if not)
$ terraform fmt -check
# Show diff of what would change
$ terraform fmt -diff
Using fmt in CI/CD
The -check flag is perfect for CI pipelines — it fails the build if anyone committed unformatted code:
# GitHub Actions example
- name: Check Terraform formatting
run: terraform fmt -check -recursive
If the check fails, the developer runs terraform fmt locally and pushes a fix.
terraform validate — Check for Errors
terraform validate checks your configuration for syntax errors, invalid references, and type mismatches. It does not make any API calls — it’s a pure local check.
$ terraform validate
Success! The configuration is valid.
What validate Catches
| Error Type | Example |
|---|---|
| Syntax errors | Missing closing brace } |
| Invalid references | aws_s3_bucket.nonexistent.arn (resource doesn’t exist) |
| Type mismatches | Passing a string where a number is expected |
| Missing required arguments | Resource is missing a required field |
| Invalid argument names | Typo in an argument name |
What validate Does NOT Catch
| Not Caught | Why |
|---|---|
| Invalid AWS resource configs | Requires API call to validate |
| Permissions issues | Requires API call |
| Duplicate resource names in AWS | Only detected during apply |
| State drift | Requires comparing with real infrastructure |
Example: validate Catches a Typo
resource "aws_s3_bucket" "example" {
buckettt = "my-bucket" # Typo — extra 't'
}
$ terraform validate
╷
│ Error: Unsupported argument
│
│ on main.tf line 2, in resource "aws_s3_bucket" "example":
│ 2: buckettt = "my-bucket"
│
│ An argument named "buckettt" is not expected here. Did you mean "bucket"?
╵
💡 Tip: You must run
terraform initbeforeterraform validate. Validation needs the provider schemas (downloaded during init) to know which arguments are valid.
Difference Between fmt and validate
| Aspect | terraform fmt |
terraform validate |
|---|---|---|
| Purpose | Code style | Code correctness |
| Changes files | Yes (rewrites in place) | No (read-only check) |
| Requires init | No | Yes |
| Makes API calls | No | No |
| Catches | Formatting issues | Syntax errors, bad references |
Run both, every time. Format first, then validate.
Pre-Commit Hooks
Automate both checks before every Git commit using pre-commit hooks:
$ cat .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.86.0
hooks:
- id: terraform_fmt
- id: terraform_validate
Install the pre-commit framework and the hooks:
$ pip install pre-commit
$ pre-commit install
Now every git commit automatically checks formatting and validation. If either fails, the commit is blocked until you fix the issue.
Common Formatting Rules
Terraform’s canonical format follows these rules:
| Rule | Example |
|---|---|
| 2-space indentation | All nested content uses 2 spaces |
Aligned = signs |
Arguments in the same block align their = |
| One blank line between blocks | Separates resource blocks for readability |
| No trailing whitespace | Clean line endings |
| Closing brace on its own line | } is never on the same line as content |
What’s Next?
You’ve covered the entire HCL syntax chapter. Time to test your knowledge with the practice exercises.