Test Phase
Validate infrastructure code before it reaches any environment. Testing in IDLC happens at multiple levels.
Testing Levels
1. Static Analysis
Run before every commit via pre-commit hooks:
# Format check
tofu fmt -check -recursive
# Linting
tflint --enable-rule=terraform_naming_convention
# Security scanning
tfsec .
2. Plan Validation
Verify that Terraform/OpenTofu plans produce expected results:
tofu init
tofu plan -var-file=test.tfvars
3. Integration Testing
Use tools like Terratest to validate actual infrastructure:
func TestS3BucketModule(t *testing.T) {
terraformOptions := &terraform.Options{
TerraformDir: "../../modules/s3/bucket",
Vars: map[string]interface{}{
"bucket_name": "test-bucket-" + random.UniqueId(),
"bucket_tags": map[string]string{"env": "test"},
},
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
bucketID := terraform.Output(t, terraformOptions, "bucket")
assert.NotEmpty(t, bucketID)
}
4. Policy as Code
Enforce organizational policies using OPA or Sentinel:
# policy/s3_encryption.rego
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not resource.change.after.server_side_encryption_configuration
msg := "S3 buckets must have encryption enabled"
}
CI Pipeline Integration
Tests should run automatically on every pull request via your CI system (GitHub Actions, Atlantis, etc.).
Start with static analysis and plan validation. Add integration tests as your module library matures.