When managing infrastructure as code(IaC) with Terraform, it's essential to ensure the code's reliability through automated testing. Terratest(by Gruntwork.io) is a powerful Go-based library designed to test infrastructure code, allowing you to validate configurations, deployment behavior, and integration with cloud services.
What is Terratest?
Terratest is an open-source testing framework that provides:
- Integration Tests: Deploy infrastructure and verify its behavior.
- Unit Tests: Test individual modules or small parts of the code.
- Infrastructure Validation: Ensure deployed resources meet your expectations.
It’s written in Go and works seamlessly with Terraform.
Why Use Terratest?
- Catch Issues Early: Validate Terraform code before deploying to production.
- Automated Validation: Test infrastructure changes in CI/CD pipelines.
- Multi-Cloud Support: Works with Azure, AWS, GCP, and more.
- Reusable Tests: Write tests once and reuse them across projects.
Prerequisites
To follow along, ensure you have:
- Terraform Installed: Download and install Terraform from terraform.io.
- Go Installed: Install Go from golang.org.
- Azure CLI: Set up the Azure CLI for authentication.
- Terratest Library: Install Terratest by adding it to your Go project dependencies.
- An Azure Subscription: Required to deploy test resources.
Setting Up Terratest for Terraform
1. Install Go and Set Up a Test Project
Create a new Go module for your tests:
mkdir terratest-azure
cd terratest-azure
go mod init terratest-azure
Add Terratest as a dependency:
go get github.com/gruntwork-io/terratest/modules/terraform
2. Set Up a Terraform Module for Azure
Let’s create a Terraform module for an Azure Storage Account:
# modules/storage_account/main.tf
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "rg-terratest-${var.env}"
location = "East US"
}
resource "azurerm_storage_account" "example" {
name = "stterratest${var.env}"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
Environment = var.env
}
}
variable "env" {
description = "Environment (e.g., 'test')"
}
output "storage_account_name" {
value = azurerm_storage_account.example.name
}
3. Write a Terratest for Azure
Create a Go test file (e.g., storage_account_test.go):
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestTerraformAzureStorage(t *testing.T) {
t.Parallel()
// Configure Terraform options
terraformOptions := &terraform.Options{
TerraformDir: "../modules/storage_account",
Vars: map[string]interface{}{
"env": "test",
},
}
// Clean up resources after test
defer terraform.Destroy(t, terraformOptions)
// Deploy the module
terraform.InitAndApply(t, terraformOptions)
// Validate the storage account name
storageAccountName := terraform.Output(t, terraformOptions, "storage_account_name")
assert.Contains(t, storageAccountName, "stterratesttest") // Azure names are case-insensitive
}
3. Run the Test
- Initialize Go modules:
go mod init terratest-azure-demo
go mod tidy
- Set Azure credentials (using environment variables):
export ARM_SUBSCRIPTION_ID="<your-subscription-id>"
export ARM_TENANT_ID="<your-tenant-id>"
export ARM_CLIENT_ID="<your-client-id>"
export ARM_CLIENT_SECRET="<your-client-secret>"
- Execute the test:
This will initialize and apply the Terraform configuration, validate the outputs, and clean up the deployed resources.
go test -v -timeout 30m
Expected Output:
PASS: TestTerraformAzureStorage
Using Terratest in CI/CD
To integrate Terratest into your CI/CD pipelines:
- Setup Environment: Ensure Terraform, Go, and Azure CLI are installed in the CI/CD environment.
- Run Tests: Execute the test scripts as part of your pipeline.
- Handle Secrets: Use environment variables or secret management tools for sensitive data like Azure credentials.
Best Practices
- Use Isolated Test Environments: Test in separate Azure resource groups or subscriptions.
- Automate Cleanup: Always use terraform.Destroy to remove resources after tests.
- Modularize Tests: Write reusable test functions for common scenarios.
- Validate Outputs: Use Terratest assertions to check resource outputs.
Conclusion
Terratest empowers teams to validate Azure infrastructure code with confidence. By automating tests, you reduce risks and accelerate deployments. Start with simple resources like storage accounts, then expand to complex workflows like VM deployments or AKS clusters.
Further Reading:
Published Jan 28, 2025
Version 1.0RavinderGupta
Microsoft
Joined November 18, 2024
Azure Infrastructure Blog
Follow this blog board to get notified when there's new activity