Automating AWS Infrastructure Testing With Terratest
Terratest validates Terraform-based AWS resources, running checks and tearing them down afterward to catch issues early and prevent production misconfigurations.
Join the DZone community and get the full member experience.
Join For FreeOrganizations adopting Infrastructure as Code (IaC) on AWS often struggle with ensuring that their infrastructure is not only correctly provisioned but also functioning as intended once deployed. Even minor misconfigurations can lead to costly downtime, security vulnerabilities, or performance issues.
Traditional testing methods — such as manually inspecting resources or relying solely on static code analysis — do not provide sufficient confidence for production environments. There is a pressing need for an automated, reliable way to validate AWS infrastructure changes before they go live.
Solution
Terratest provides an automated testing framework written in Go, designed specifically to test infrastructure code in real-world cloud environments like AWS. By programmatically deploying, verifying, and destroying resources, Terratest bridges the gap between writing IaC (e.g., Terraform) and confidently shipping changes. Here’s how it works:
Below is a detailed guide on how to achieve AWS infrastructure testing using Terratest with Terraform, along with sample code snippets in Go. This workflow will help you provision AWS resources, run tests against them to ensure they work as intended, and then tear everything down automatically.
Prerequisites
Install Terraform
Download and install Terraform from the official site.
Install Go
Terratest is written in Go, so you’ll need Go installed. Download Go from the official site.
Set Up AWS Credentials
Ensure your AWS credentials are configured (e.g., via ~/.aws/credentials or environment variables like AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
).
Initialize a Go Module
In your project directory, run:
go mod init github.com/yourusername/yourproject
go mod tidy
Add Terratest to Your go.mod
In your project/repo directory, run:
go get github.com/gruntwork-io/terratest/modules/terraform
go get github.com/stretchr/testify/assert
Sample Terraform Configuration
Create a simple Terraform configuration that launches an AWS EC2 instance. Put the following files in a directory named aws_ec2_example (or any name you prefer).
Save it as main.tf for reference.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
required_version = ">= 1.3.0"
}
provider "aws" {
region = var.aws_region
}
resource "aws_instance" "example" {
ami = var.ami_id
instance_type = "t2.micro"
tags = {
Name = "Terratest-Example"
}
}
output "instance_id" {
value = aws_instance.example.id
}
Next, variables.tf:
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "ami_id" {
type = string
default = "ami-0c55b159cbfafe1f0" # Example Amazon Linux AMI (update as needed)
}
Terratest Code Snippet
Create a Go test file in a directory named test (or you can name it anything, but test is conventional). For example, aws_ec2_test.go:
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestAwsEC2Instance(t *testing.T) {
// Define Terraform options to point to the Terraform folder
terraformOptions := &terraform.Options{
TerraformDir: "../aws_ec2_example",
// Optional: pass variables if you want to override defaults
Vars: map[string]interface{}{
"aws_region": "us-east-1",
"ami_id": "ami-0c55b159cbfafe1f0",
},
}
// At the end of the test, destroy the resources
defer terraform.Destroy(t, terraformOptions)
// Init and apply the Terraform configuration
terraform.InitAndApply(t, terraformOptions)
// Fetch the output variable
instanceID := terraform.Output(t, terraformOptions, "instance_id")
// Run a simple assertion to ensure the instance ID is not empty
assert.NotEmpty(t, instanceID, "Instance ID should not be empty")
}
What This Test Does
- Initializes and applies the Terraform configuration in
../aws_ec2_exampl
e. - Deploys an EC2 instance with the specified AMI in us-east-1.
- Captures the
instance_id
Terraform output. - Verifies that the instance ID is not empty using Testify’s assert library.
- Destroys the resources at the end of the test to avoid incurring ongoing costs.
Running the Tests
- Navigate to the directory containing your Go test file (e.g., test directory).
- Run the following command:
go test -v
- Observe the output:
- You’ll see Terraform initializing and applying your AWS infrastructure.
- After the test assertions pass, Terraform will destroy the resources.
Conclusion
By following these steps, you can integrate Terratest into your AWS IaC workflow to:
- Provision AWS resources using Terraform.
- Test them programmatically with Go-based tests.
- Validate that your infrastructure is configured properly and functioning as expected.
- Tear down automatically, ensuring that you’re not incurring unnecessary AWS costs and maintaining a clean environment for repeated test runs.
Opinions expressed by DZone contributors are their own.
Comments