Terraform testing with Terratest tutorial for beginners — Complete Guide
A practical, in-depth guide to Terraform testing with Terratest tutorial for beginners with examples.
INTRO
Infrastructure as Code (IaC) promises repeatable, version‑controlled environments, but without proper testing you’re still gambling on whether the generated resources actually match expectations. In real‑world projects, a single mis‑typed variable or an outdated module can spin up insecure networks, blow up budgets, or cause downstream services to fail—issues that are far more painful to debug after the fact than to catch early.
Terratest bridges that gap by letting you write automated, language‑native tests that spin up real Terraform plans, assert on the resulting state, and tear everything down cleanly. It’s the “unit test” you never knew you needed for your cloud infrastructure, and it integrates seamlessly with your existing CI pipelines.
If you’ve ever manually ran terraform apply just to see if a change works, you’ll know the pain of “it works on my machine.” Terratest eliminates that friction, giving you confidence that every PR is validated against a real, disposable environment before it ever touches production.
WHAT YOU'LL LEARN
- How to set up a Go test harness that runs Terraform commands programmatically.
- Writing assertions against Terraform outputs and cloud provider resources using the Terratest library.
- Managing test lifecycles: provisioning, validation, and automated teardown to keep costs low.
- Structuring your repository for reusable test modules and shared fixtures.
- Integrating Terratest into CI/CD (GitHub Actions, GitLab CI) for gate‑keeping pull requests.
- Common pitfalls—state file handling, parallel execution, and flaky network calls—and how to avoid them.
A SHORT CODE SNIPPET
// Example: Verify that a VPC CIDR block matches the expected value
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestVpcCidr(t *testing.T) {
t.Parallel()
// Define Terraform options pointing to the module under test
terraformOptions := &terraform.Options{
TerraformDir: "../examples/vpc",
Vars: map[string]interface{}{
"cidr_block": "10.0.0.0/16",
},
}
// Clean up resources with "terraform destroy" at the end of the test
defer terraform.Destroy(t, terraformOptions)
// Run "terraform init" and "terraform apply"
terraform.InitAndApply(t, terraformOptions)
// Grab the output value and assert
vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr")
assert.Equal(t, "10.0.0.0/16", vpcCidr)
}
This snippet shows the core Terratest workflow: provision, validate, and destroy—all within a single, reproducible test.
KEY TAKEAWAYS
- Terratest turns Terraform plans into executable tests, catching errors before they reach production.
- Proper test isolation (parallelism, unique resource names, and deferred destroy) keeps costs predictable and tests reliable.
- Embedding Terratest in CI creates a safety net that enforces infrastructure quality on every pull request.
- Understanding common failure modes—state file conflicts, provider rate limits, and environment variables—prevents flaky builds.
👉 Read the complete guide with step-by-step examples, common mistakes, and production tips:
Terraform testing with Terratest tutorial for beginners — Complete Guide
Top comments (0)