Exploring Testing Strategies for Terraform Projects

Benjamin Garside
Version 1
Published in
4 min readJul 29, 2024
Meme — “60% of the time, deployments work every time”

When working with Terraform, ensuring your infrastructure as code (IaC) is robust and reliable is crucial. Different types of testing can help you catch issues early and maintain high-quality code.

Let’s dive into the pros and cons of four key testing strategies: static code analysis, unit tests, integration tests, and end-to-end testing.

Static Code Analysis

Static code analysis tools look at the raw code in your project (in this case your .tf files) and check it for potential problems, for example; formatting issues, configuration issues, and security issues. This is all done without actually executing the code.

Examples

Here are some examples of static code analysis tools you could use:

  • tf validate This is a Terraform native tool that “runs checks that verify whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state” (HashiCorp Docs)
  • checkov A tool created by Prisma Cloud that scans either your TF files or optionally your TF plan files to find common misconfigurations, mainly based on security risks
  • tfsec Is a very popular open-source tool currently owned by Aqua Security.

There are many more tools out there as this is a very big market at the moment.

Pros

  • Early Detection — Catches issues before any code is actually run
  • Speed — Fast to run and get results
  • Stable — Very unlikely to get flaky tests

Cons

  • Limited Scope — Can’t catch runtime errors or issues that only appear during execution
  • Limited Confidence — due to the scope of testing only a limited amount of confidence can be achieved

Unit Tests

Unit tests in Terraform are designed to validate the logic within your infrastructure as code, ensuring that configuration changes do not introduce errors. They operate by running against test-specific, ephemeral resources, which means they don’t risk your existing infrastructure or state. Essentially, unit tests in Terraform allow you to verify that the actual values in your configurations match the expected values without deploying real resources.

Unit Test require impacting actual infrastructure, following the steps;

  1. Deploy infrastructure
  2. Validate it works
  3. Destroy the infrastructure

Examples

  • terratest A testing framework by Gruntwork that allows you to write Go tests for your Terraform modules, ensuring they behave as expected.
  • kitchen-terraform A (soon to deprecated) open-source framework based on Test Kitchen that allows for automating tests in Terraform
  • Terraform Tests a Terraform native tool for unit testing. It “lets authors validate that module configuration updates do not introduce breaking changes”

Pros

  • Isolated Testing — Tests individual components in isolation, making it easier to pinpoint issues
  • Good level of confidence — Tests a whole module giving a higher level of confidence

Cons

  • Mocking Complexity — Some tests require endpoints and resources to be mocked and this can add a level of complexity
  • Requires infrastructure — Unlike static testing, to run a unit test you must deploy actual infrastructure

Integration Tests

Integration Tests take Unit test to the next level but running multiple Unit Tests at once, and then validating that they work together as expected. These also require making changes to actual infrastructure and so tend to be run against test-specific, ephemeral resources.

Examples

The same tools used for Unit Tests can be used for integration tests, all the mentioned tools have the functionality of managing each unit in a suite of tests, allowing the testing of one from another.

Pros

  • Comprehensive — Tests interactions between components, catching issues that unit tests might miss
  • Realistic — Provides a more realistic assessment of your code’s behaviour in a real environment

Cons

  • Slow to run — Running multiple tests takes time
  • Resource Intensive — Requires more resources and setup, which can be costly

End-to-End Testing

End-to-end (E2E) testing involves testing the entire Terraform workflow from start to finish. This includes provisioning infrastructure, deploying applications, and verifying that everything works as expected.

Examples

Using a combination of tools like Terratest and InSpec, you can create E2E tests that deploy and validate your entire infrastructure. It is very likely that you will also need to write custom code or pipelines to manage the testing.

Pros

  • High Confidence — Provides high confidence that the infrastructure works as expected
  • User Perspective — Tests the entire workflow from start to finish, mimicking real user scenarios

Cons

  • Complex and Time-Consuming — Setting up and maintaining E2E tests can be complex and time-consuming
  • Expensive — Requires significant resources, both in terms of time and cost

Conclusion

Each type of testing has its strengths and weaknesses, and the best approach often involves a combination of these strategies.

Static code analysis is great for catching issues early, unit tests ensure individual components work correctly, integration tests verify interactions between components, and end-to-end tests provide a comprehensive assessment of your entire workflow. By leveraging these testing strategies, you can ensure your Terraform projects are robust, reliable, and ready for production.

Happy testing! 🚀

About the Author

Benjamin Garside is a Senior Azure DevOps Engineer here at Version 1.

--

--