Skip to main content
terraform fmt and terraform validate: Format and Check Your Code

terraform fmt and terraform validate: Format and Check Your Code

Key Takeaway

How to use terraform fmt to auto-format HCL files and terraform validate to check syntax. Includes terraform fmt -check, -recursive

Table of Contents

Introduction

Every Terraform project needs consistent formatting and syntax validation. terraform fmt auto-formats your HCL files to the canonical style, while terraform validate checks your configuration for errors before you run plan or apply.

This guide covers both commands with all their flags, practical examples, and CI/CD integration.

terraform fmt — Auto-Format HCL Files

terraform fmt rewrites Terraform configuration files to the canonical format and style. It applies a subset of the Terraform language style conventions.

Basic Usage

# Format all .tf files in the current directory
terraform fmt

# Format and show what changed
terraform fmt -diff

# Format recursively (all subdirectories)
terraform fmt -recursive

What terraform fmt Changes

  • Indentation: Normalizes to 2 spaces
  • Alignment: Aligns = signs in attribute blocks
  • Whitespace: Removes trailing whitespace, normalizes blank lines
  • Quotes: Standardizes string quoting

Before:

resource "aws_instance" "web" {
    ami = "ami-12345678"
    instance_type="t3.micro"
  tags={
    Name    = "my-instance"
        Environment="production"
  }
}

After terraform fmt:

resource "aws_instance" "web" {
  ami           = "ami-12345678"
  instance_type = "t3.micro"
  tags = {
    Name        = "my-instance"
    Environment = "production"
  }
}

All terraform fmt Flags

FlagDescriptionExample
-checkCheck if files are formatted (exit 0 if yes, 3 if no)terraform fmt -check
-diffShow the formatting differencesterraform fmt -diff
-recursiveProcess subdirectories recursivelyterraform fmt -recursive
-list=falseDon’t list formatted filesterraform fmt -list=false
-write=falseDon’t write changes (dry run)terraform fmt -write=false -diff
-no-colorDisable color outputterraform fmt -no-color

terraform fmt -check (CI/CD)

The -check flag is designed for CI/CD pipelines. It returns exit code 0 if all files are properly formatted, or exit code 3 if any files need formatting:

# Check without modifying files
terraform fmt -check -recursive

# In a CI pipeline — fail the build if not formatted
terraform fmt -check -recursive -diff

terraform fmt -recursive

By default, terraform fmt only processes the current directory. Use -recursive to format your entire project:

# Format everything including modules
terraform fmt -recursive

# Check everything in CI
terraform fmt -check -recursive

Combining Flags

# Dry run: show what would change across all directories
terraform fmt -check -diff -recursive

# Format everything, show changes, suppress file list
terraform fmt -recursive -diff -list=false

terraform validate — Check Configuration Syntax

terraform validate checks whether a configuration is syntactically valid and internally consistent. It checks types, required attributes, and references without accessing any remote services.

Basic Usage

# Must run init first (validates provider schemas)
terraform init
terraform validate

Successful output:

Success! The configuration is valid.

Error output:

╷
│ Error: Missing required argument
│
│   on main.tf line 3, in resource "aws_instance" "web":
│    3: resource "aws_instance" "web" {
│
│ The argument "ami" is required, but no definition was found.
╵

What terraform validate Checks

  • Syntax errors: Missing braces, commas, quotes
  • Type errors: Wrong attribute types (string where number expected)
  • Required attributes: Missing mandatory fields
  • Reference errors: Referencing resources or variables that don’t exist
  • Block structure: Invalid nested blocks

What terraform validate Does NOT Check

  • Whether resources actually exist in the cloud
  • Whether values are valid (e.g., valid AMI IDs)
  • Whether you have proper credentials
  • Runtime errors that only appear during apply

JSON Output

For programmatic use:

terraform validate -json
{
  "valid": false,
  "error_count": 1,
  "warning_count": 0,
  "diagnostics": [
    {
      "severity": "error",
      "summary": "Missing required argument",
      "detail": "The argument \"ami\" is required..."
    }
  ]
}

terraform fmt vs terraform validate

Featureterraform fmtterraform validate
What it doesFormats HCL code styleChecks syntax and logic
Needs init?NoYes (needs provider schemas)
Modifies files?Yes (unless -check)No
Catches syntax errors?Only formatting issuesYes
Catches logic errors?NoYes (missing refs, wrong types)
CI/CD usagefmt -check (exit 3 = unformatted)validate (exit 1 = invalid)

Use both — they catch different things:

# Full validation pipeline
terraform fmt -check -recursive    # Style check
terraform init -backend=false      # Init without backend
terraform validate                 # Syntax/logic check
terraform plan                     # Plan against real infra

CI/CD Integration

GitLab CI

validate:
  stage: test
  script:
    - terraform fmt -check -recursive -diff
    - terraform init -backend=false
    - terraform validate
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

GitHub Actions

- name: Terraform Format Check
  run: terraform fmt -check -recursive -diff

- name: Terraform Validate
  run: |
    terraform init -backend=false
    terraform validate    

Pre-commit Hook

Create .pre-commit-config.yaml:

repos:
  - repo: https://github.com/antonbabenko/pre-commit-terraform
    rev: v1.86.0
    hooks:
      - id: terraform_fmt
      - id: terraform_validate

Or a simple git hook in .git/hooks/pre-commit:

#!/bin/sh
terraform fmt -check -recursive
if [ $? -ne 0 ]; then
  echo "Run 'terraform fmt -recursive' to fix formatting"
  exit 1
fi
ToolPurpose
terraform fmtOfficial formatter (style only)
terraform validateOfficial validator (syntax + logic)
TFLintLinter for best practices + cloud-specific rules
CheckovSecurity and compliance scanning
tfsecStatic security analysis

Hands-On Courses

Learn by doing with interactive courses on CopyPasteLearn:

Conclusion

terraform fmt and terraform validate are the foundation of Terraform code quality. Use terraform fmt -check -recursive in CI to enforce consistent formatting, and terraform validate after init to catch syntax and reference errors before they reach terraform plan. Together with linters like TFLint, they form a complete validation pipeline.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.