Modern QA2026Static Validation: The First Gate — tiles
Log inJoin
2 / 75 · 08 Infrastructure as Code Testing · Terraform Validation← prev⊞ allnext →☰ Read as one page

1.2Static Validation: The First Gate

Every Terraform pipeline should start with zero-cost static checks. These run in seconds, require no cloud credentials, and catch a surprising number of issues.

Format and Syntax Checks

# Format check -- enforces consistent style
# -check returns a non-zero exit code if files need formatting
# -recursive scans all subdirectories
# -diff shows what would change
terraform fmt -check -recursive -diff

# Syntax and type validation -- catches typos, missing required fields
# -backend=false skips backend initialization (no credentials needed)
terraform init -backend=false
terraform validate

The distinction between fmt and validate matters. fmt enforces style -- consistent indentation, alignment, and spacing. validate checks structural correctness -- does this HCL parse? Are all required arguments present? Do type constraints match?

What terraform validate Catches

# Example: terraform validate catches this missing required attribute
resource "aws_s3_bucket" "data" {
  # Oops -- forgot the bucket name
  # terraform validate will catch this
  acl = "private"
}

# It also catches type mismatches:
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  count         = "three"  # ERROR: count must be a number, not a string
}

# And references to undeclared resources:
resource "aws_security_group_rule" "allow_http" {
  security_group_id = aws_security_group.nonexistent.id  # ERROR
  type              = "ingress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
}

Integrating Static Checks into Pre-Commit Hooks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/antonbabenko/pre-commit-tf
    rev: v1.88.0
    hooks:
      - id: terraform_fmt
      - id: terraform_validate
      - id: terraform_docs
        args:
          - --hook-config=--path-to-file=README.md
          - --hook-config=--add-to-existing-file=true
      - id: terraform_tflint
        args:
          - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl

Pre-commit hooks ensure that no developer can commit malformed Terraform. This is your cheapest quality gate.