Terraform Testing Matrix

This guide covers choosing testing depth proportional to risk and cost for Terraform and OpenTofu modules.

Testing Layers

  1. Static checks: format, validate, lint, security scan
  2. Plan checks: reviewed execution intent
  3. Native tests: module-level assertions (terraform test / tofu test)
  4. Integration tests: ephemeral apply + live assertions
  5. Terratest: workflow/system validation in Go for complex scenarios

Tier A: All Changes (Minimum)

Required for every change:

  • fmt -check
  • init -backend=false + validate
  • Lint + security scan
  • Reviewed plan artifact

Use for low-risk isolated updates.

Tier B: Shared Modules and Medium-Risk Changes

Add on top of Tier A:

  • Native test runs for module behavior
  • Targeted integration apply tests in ephemeral environment
  • Policy checks on plan JSON

Typical triggers:

  • Shared module changes
  • IAM/network updates
  • Encryption/data-boundary updates

Tier C: High-Risk Production Changes

Add on top of Tier A + B:

  • Staged rollout (dev -> stage -> prod)
  • Rollback rehearsal or documented rollback proof
  • Manual owner approvals + security/compliance sign-off
  • Post-apply drift detection

Typical triggers:

  • State backend migration
  • Major refactor with address changes
  • Foundational platform stack changes

Native Test Guidance

When to Use command = plan

  • Input validation
  • Static contract checks
  • Argument shape assertions not relying on computed runtime values

When to Use command = apply

  • Computed attributes known only after creation
  • Assertions over provider-populated fields
  • Set/list semantics unresolved in plan stage

Frequent Pitfalls

  • Asserting unknown values in plan mode
  • Indexing set-type blocks directly
  • Assuming mocked providers equal integration confidence

Terratest Guidance

Use Terratest when native tests are insufficient:

  • Cross-module workflows
  • External API verification (health checks, connectivity)
  • Failover/disaster-recovery scenarios
  • Multi-step lifecycle tests (apply-change-destroy)

Terratest Test Pyramid

  • Fast: contract tests (mocked or plan-level)
  • Medium: environment integration tests (ephemeral)
  • Slow: limited end-to-end smoke tests for critical paths

Cost Controls

  • Tag tests by class (unit, integration, destructive)
  • Parallelize only isolated stacks
  • Auto-clean resources with TTL tags
  • Run expensive tests nightly and on protected branches

Test Framework Scaffolding

.
  test/
    terratest/
      go.mod
      helpers/
      examples/
      network_test.go
    native/
      main.tftest.hcl
  Makefile

Minimal Makefile targets:

test-native:
    terraform test

test-terratest:
    go test ./test/terratest -timeout 45m

Example Command Flow

terraform fmt -check
terraform init -backend=false
terraform validate
terraform plan -out=plan.bin
terraform show -json plan.bin > plan.json
conftest test plan.json --policy policy/
terraform test

Terratest stage:

go test ./test -run TestCriticalPath -timeout 45m

Quick Selection Rules

Change Type Testing Tier
Tiny tag change in isolated stack Tier A
Module contract change Tier A + Tier B
Refactor with moved and shared impact Tier A + B + targeted Terratest
Production identity/network/encryption/state changes Tier A + B + C + Terratest smoke

Done Criteria

Not done until:

  • Required tier passes
  • Reviewed plan is approved
  • Apply path is trusted and auditable
  • Evidence artifacts are retained

results matching ""

    No results matching ""