TechAnek

Setting up infrastructure manually can be both time-consuming and challenging. This is where Infrastructure as Code (IaC) tools come into play, offering automation for provisioning and managing infrastructure. With IaC, automation is achieved for setting up resources like virtual machines, storage, and more. As infrastructure increasingly becomes code, implementing unit and integration tests becomes crucial to ensure its reliability. This blog explores what IaC is and why testing it matters, followed by a detailed look at using Terratest for infrastructure testing.

Let’s dive in!

What is Infrastructure as Code (IaC)?

Infrastructure as Code refers to the practice of automating the provisioning and configuration of infrastructure using code, rather than manually setting it up through a graphical interface. For instance, virtual machines can be defined and deployed, configured, and integrated with monitoring systems—all through code. Examples of IaC tools include Terraform, Packer, and Ansible.

IaC allows tracking infrastructure changes in version control systems like Git, creating reusable templates and modules, and deploying consistent configurations across multiple environments and regions. One of the major benefits of IaC is disaster recovery, as it enables quick replication of infrastructure in different environments or regions when needed.

What is Terratest?

Terratest is a Go-based library created by Gruntwork that assists in writing and automating tests for Infrastructure as Code (IaC) projects, particularly those developed with Terraform, Packer, or for cloud platforms like AWS and Google Cloud, as well as Kubernetes clusters. It provides several utilities and patterns to help with:

Customized Bullet List
  • Testing Docker images, Helm charts, and Packer templates.
  • Interacting with cloud provider APIs, including AWS and Azure.

With Terratest, both basic sanity checks and detailed functional tests can be conducted on infrastructure code. This tool helps identify and resolve issues efficiently within infrastructure configurations. Additionally, Terratest supports compliance testing, ensuring that infrastructure components, such as newly created S3 buckets, adhere to best practices like enabling versioning and encryption.

Advantages of Testing Infrastructure as Code (IaC)

Infrastructure as Code (IaC) has become a cornerstone of modern cloud infrastructure management, allowing teams to automate the provisioning and management of infrastructure using code. However, just like any software application, IaC must be tested to ensure that it functions correctly and securely in a production environment. Here are some key reasons why testing IaC is essential:

1. Testing helps catch configuration errors early, preventing costly issues in production.
2. Ensures the same infrastructure setup in development, staging, and production environments.
3. Validates security configurations, preventing vulnerabilities like misconfigured access control.
4. Automated tests in CI/CD pipelines allow for faster, more reliable infrastructure changes.

Pre-requisite to run the Terratest

To run Terratest for testing Infrastructure as Code (IaC) in this blog, ensure the following prerequisites are met:

1. Go Lang (Version 1.20 or Above): Terratest is built using Go, requiring version 1.20 or higher. The current Go version can be checked by running:

				
					go version
				
			
To upgrade or install Go, visit the Go download page.

2. Terraform:Since this blog focuses on testing Terraform code, having Terraform installed is essential. The Terraform version can be checked with:

				
					terraform version
				
			
If Terraform is not already installed, download Terraform from the official Terraform website.

Setting Up Terratest for Terraform

Now we will execute some integration tests using terratest. Once the installation steps are complete, We’ll start by writing the test using Go and execute it.

  First things first:
        1. Test file name should have _test in its name for example sample_test.go. This is how a Go looks for the test files.
        2. Test function name should start with Test with T being in capital letter. For example, TestFunction would work but testFunction will throw
             an error “no tests to run”.

Setup the file structure
				
					//Create a new project directory:
terratest-example/
├── main.tf               # Terraform configuration
├── outputs.tf            # Terraform outputs
├── variables.tf          # Terraform variables
├── test/
    └── main_test.go      # Terratest code
				
			
Writing a Test with Terratest

Here’s an example test for an AWS S3 bucket using Terratest:
1. Terraform Configuration

				
					# main.tf
resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name
  acl    = "private"
}

# variables.tf
variable "bucket_name" {
  description = "The name of the S3 bucket."
}

# outputs.tf
output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}
				
			

2. Test Code

				
					// test/main_test.go
package test

import (
	"testing"
	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
)

func TestS3BucketCreation(t *testing.T) {
	t := testing.T()
	
	// Define Terraform options
	terraformOptions := &terraform.Options{
		TerraformDir: "../",
		Vars: map[string]interface{}{
			"bucket_name": "terratest-example-bucket",
		},
	}

	// Ensure infrastructure is destroyed after test
	defer terraform.Destroy(t, terraformOptions)

	// Run Terraform Init and Apply
	terraform.InitAndApply(t, terraformOptions)

	// Get output values
	bucketName := terraform.Output(t, terraformOptions, "bucket_name")

	// Assert bucket name matches expected value
	assert.Equal(t, "terratest-example-bucket", bucketName)
}
				
			

Now, run the terraform init command. After that go to test directory and run the following commands to run the test:

				
					go mod init <module-name> //e.g. terratest-test
go mod tidy
go test -v
				
			

After running this command, the logs can be viewed where Terratest checks the Terraform code and identifies any errors or vulnerabilities, if present.

Conclusion

Terratest bridges the gap between IaC and software testing, enabling teams to validate infrastructure with confidence. By incorporating Terratest into workflows, robust, reliable, and cost-effective infrastructure provisioning can be ensured. Starting small, iterating, and gradually expanding test coverage allows for achieving the full benefits of IaC testing.

Leave a Reply

Your email address will not be published. Required fields are marked *