Testing Terraform Code with terraform test
Modules are code that many teams depend on, so they deserve tests. Terraform includes a test framework: .tftest.hcl files with runs and assertions.
A plan-only test
# tests/naming.tftest.hcl
variables {
environment = "staging"
domain = "shop.example.com"
}
run "bucket_name_includes_environment" {
command = plan
assert {
condition = aws_s3_bucket.site.bucket == "shop.example.com-staging"
error_message = "Bucket name should be <domain>-<environment>."
}
}
run "rejects_unknown_environment" {
command = plan
variables {
environment = "qa"
}
expect_failures = [var.environment] # the validation block should reject this
}
terraform test
command = plan tests run without creating anything. Without it, a run applies real infrastructure and destroys it at the end, which is slower but proves the module really works.
Mock providers
mock_provider "aws" {}
run "creates_two_buckets" {
command = apply # "applies" against the mock: fast, no cloud account needed
assert {
condition = length(aws_s3_bucket.buckets) == 2
error_message = "Expected two buckets."
}
}
Guardrails in the configuration itself
resource "aws_instance" "web" {
instance_type = var.instance_type
lifecycle {
precondition {
condition = var.environment != "prod" || startswith(var.instance_type, "m")
error_message = "Production must use general-purpose (m*) instances."
}
}
}
check "site_is_up" {
data "http" "home" {
url = "https://${var.domain}/healthz"
}
assert {
condition = data.http.home.status_code == 200
error_message = "Health check failed after apply."
}
}
- Variable validation rejects bad inputs.
- Preconditions/postconditions enforce rules on resources.
- Check blocks report problems (as warnings) without blocking the apply.
Combine with static checks (terraform validate, tflint, security scanners) in CI for full coverage.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.