Testing Terraform Configurations
Fast recall
Quick revision
Core answer
Whether you know that Terraform testing is more than just `terraform validate` and can describe a testing pyramid that covers static analysis, unit-like module testing, and integration tests.
Treating `terraform plan` as sufficient testing, which doesn't catch runtime errors, security misconfigurations, or logic errors that only appear with real infrastructure.
Describe the Terraform testing pyramid: validate/fmt -> tflint/checkov (static) -> terraform test (unit, 1.6+) -> Terratest (integration with real infra), and explain the cost/speed trade-off at each layer.
Interview-ready guide
Interview answer
Testing Terraform separates into three levels: static analysis that runs without touching the cloud, integration testing that provisions real resources, and contract testing that verifies module interfaces. Most teams start with static analysis and add integration testing for critical modules.
Static analysis — fast, no cloud required
terraform validatechecks syntax and internal references — it catches undefined variables, invalid resource types, and type mismatches without any API calls; this runs in seconds and belongs in every pre-commit hook and CI pipelineterraform fmt -checkfails the CI build when formatting is inconsistent — the formatter is deterministic, so a format check in CI enforces that developers ranterraform fmtlocally; unformatted code does not mergetfsecandcheckovscan HCL for security misconfigurations — S3 buckets without versioning, security groups open to 0.0.0.0/0, RDS instances without encryption; these rules encode security best practices and catch common mistakes before deployment
Integration testing with Terratest
- Terratest is a Go library that calls
terraform apply, makes assertions against the provisioned infrastructure (HTTP requests, AWS API calls), and callsterraform destroy— a complete end-to-end test against real cloud resources - A Terratest test for an ECS module: apply the module with test inputs, assert the ALB responds with 200, assert the ECS service reaches steady state, destroy and confirm no resources remain
- Integration tests cost real money and take minutes to run — run them in CI on pull requests to the module repository, not on every push; tag them separately from unit tests so they can be skipped during development
Terraform native testing
- Terraform 1.6+ introduced a native
terraform testcommand and.tftest.hclfiles — test blocks provision and assert against real or mocked resources using the same HCL syntax as the configuration being tested - Mock providers in
terraform testenable unit-level assertions without real API calls — verify that a module produces the correct resource configuration given specific inputs, without provisioning anything; faster and cheaper than Terratest for logic-level assertions
Testing Terraform Configurations
Direct Answer
Test Terraform in layers: validate/fmt for syntax, tflint for best practices, checkov for security, terraform test (v1.6+) for module unit tests, and Terratest for integration tests against real infrastructure.
Code Example
# Layer 1: Built-in validation
# terraform fmt -check — formatting check in CI
# terraform validate — syntax and type checking
# Layer 2: Static analysis tools
# tflint — provider-specific best practices (e.g., invalid instance type)
# checkov -- security scanning (e.g., S3 bucket encryption, SG not open to 0.0.0.0)
# trivy -- IaC security scanning
# Layer 3: terraform test (Terraform 1.6+ native testing)
# tests/main.tftest.hcl
run "creates_vpc_with_correct_cidr" {
command = plan # or apply for real infra
variables {
cidr_block = "10.0.0.0/16"
name = "test-vpc"
}
assert {
condition = aws_vpc.main.cidr_block == "10.0.0.0/16"
error_message = "VPC CIDR block does not match input variable"
}
}
# Layer 4: Terratest (Go-based integration test)
# test/vpc_test.go
# func TestVpcModule(t *testing.T) {
# opts := terraform.Options{TerraformDir: "../modules/vpc"}
# defer terraform.Destroy(t, opts)
# terraform.InitAndApply(t, opts)
# vpcID := terraform.Output(t, opts, "vpc_id")
# assert.NotEmpty(t, vpcID)
# }
Common Mistakes & Pitfalls
Treating terraform plan as sufficient testing, which doesn't catch runtime errors, security misconfigurations, or logic errors that only appear with real infrastructure.
Check your understanding
Answer these without looking back at the article.
- How do you run Terratest in CI without exposing AWS credentials?
- What is the difference between terraform validate and tflint?
- How do you use checkov to enforce security policies in a Terraform pipeline?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.