Last Updated on June 11, 2025 by Arnav Sharma
Infrastructure as Code (IaC) offers power, but with that comes risk. A typo in a Terraform file or a misconfigured resource can easily cause an outage, a security gap, or unexpected costs.
To avoid that, we need more than just terraform plan
. We need a consistent way to validate our Terraform codeโbefore it ever touches production.
In this post, Iโll cover three tools that can help:
- Terratest: run unit-like tests on actual infrastructure
- TFLint: catch issues through static code analysis
- Pre-commit hooks: enforce quality and style before any Git commit
1. Terratest โ Infrastructure Testing with Go
Terratest is a testing framework written in Go that provisions real cloud infrastructure using your Terraform files, validates it programmatically, and destroys it once done.
When to Use It
You want to:
- Validate infrastructure logic
- Confirm naming conventions or resource outputs
- Automatically test infrastructure in CI/CD
Where to Place Terratest Files
Create a dedicated test
folder inside your Terraform repo:
/terraform-azure-storage/
โโโ main.tf
โโโ variables.tf
โโโ outputs.tf
โโโ test/
โโโ storage_test.go
Best practice: keep test logic separate from your deployment modules.
Sample Terratest File โ test/storage_test.go
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestTerraformAzureStorage(t *testing.T) {
terraformOptions := &terraform.Options{
TerraformDir: "../", // points to Terraform root
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
storageName := terraform.Output(t, terraformOptions, "storage_account_name")
assert.Contains(t, storageName, "arnav")
}
How to Run It
go test -v ./test/
Example Output
=== RUN TestTerraformAzureStorage
Terraform apply in ../
Validating output: storage_account_name = arnavstorageprod
--- PASS: TestTerraformAzureStorage (46.12s)
PASS
2. TFLint โ Static Analysis for Terraform
TFLint is a linter designed specifically for Terraform. It scans .tf
files and flags things like:
- Deprecated resource attributes
- Provider-specific issues
- Style inconsistencies
- Missing required tags or naming rules
When to Use It
Ideal for teams, pipelines, and code reviews. It helps enforce standards and best practices early.
Where to Place TFLint Configs
Place the TFLint config file in the root of your Terraform project:
/terraform-azure-storage/
โโโ main.tf
โโโ variables.tf
โโโ .tflint.hcl
You donโt need the config file unless customizing rules, but itโs recommended for consistency.
Running TFLint
tflint --init
tflint
Sample Output
Warning: azurerm_storage_account has deprecated attribute "enable_blob_encryption"
Error: Resource "azurerm_resource_group" is missing tag "owner"
Error: Unknown resource type "azurerm_storge_account"
3. Pre-Commit Hooks โ Enforce Validation Before Commits
Pre-commit hooks are scripts that automatically run before a commit is accepted in Git. These are great for:
- Runningย
terraform fmt
,ยvalidate
,ยtflint
- Preventing half-baked or inconsistent code from entering the repo
- Keeping things clean across team members
When to Use It
You’re working in a team or want automated quality enforcementโeven if you’re working solo.
Where to Place Pre-Commit Configs
At the root of your repo:
/terraform-azure-storage/
โโโ main.tf
โโโ outputs.tf
โโโ .pre-commit-config.yaml
Sample .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.78.0
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: tflint
- id: terraform_docs
Installation & Usage
Install pre-commit
(Python-based):
pip install pre-commit
pre-commit install
pre-commit run --all-files
Example Output
Terraform fmt.................................................Passed
Terraform validate............................................Passed
Terraform tflint..............................................Failed
- main.tf:5 - Missing required tags on azurerm_resource_group
Terraform docs................................................Updated
Bringing It All Together
Tool | Purpose | Where to Use |
---|---|---|
Terratest | Validate real deployed infrastructure | In a /test/ folder using Go |
TFLint | Catch static errors in .tf code | Root folder (optional .tflint.hcl ) |
Pre-commit | Automate checks before Git commits | Root folder (.pre-commit-config.yaml ) |