SummaryTerratest is a testing framework for Terraform code written by Gruntwork. In this post, I am going to discuss the usage of Terratest as well as my own personal experiences with testing Terraform code.
Testing Declarative Infrastructure as Code
Confession Time. I have not done a lot of testing in Terraform. As an experienced test-driven, software developer, this has always bothered me a bit. However, I am also a pragmatist and the value that testing declarative infrastructure code adds has never really been there for me.
There are several testing tools written for Terraform (these are listed on the Terratest documentation) and I have watched many presentations on what it looks like to use them. But they all seemed overly complex or didn’t quite provide the and you have to balance the complexity it brings with the value it adds. Many of these tools choose to focus on the wrong things as testing infrastructure code is completely different than testing imperative application code.
Application code tends to contain a lot of logic built to handle the disparate data that it receives. We need to write a test to make sure it gracefully handles this data. However, with declarative infrastructure code, the disparity is in the infrastructure provider. It never made sense to me to do any testing which didn’t actually stand up resources. Sure. You can test the logic in your code, but logic should not exist in abundance in infrastructure code anyways. Infrastructure code should be mostly free of abstractions and complexity.
Now that we have removed any tools that aren’t going to actually interact with the target environment (or unit tests). There are other tools that do the more comprehensive, integration tests. However, they have typically brought too many dependencies and complexity to the project to make up for the value they are providing.
Terratest is an open source testing framework for Terraform written by Gruntwork. It allows you to write tests for Terraform in Go (one of my favorite languages). These tests will apply a Terraform plan, then you can test various aspects of the infrastructure, and finally it will destroy that infrastructure when complete.
Here is an example test from the terratest announcement post from Gruntwork’s blog. That is a great post to read as it has more code as well as another example which includes Packer. This test will first use Terraform to spin up a webserver. Then, it uses a helper library to test a url on the server. The recommended best practice is to test whether or not the desired end state is achieved (as opposed to simply checking that an instance was created or that a service is running on that instance).
Terratest looks like a solid testing tool for Terraform code. Though I still have concerns over the length of time it will take to run all the tests since some resources can take a while to provision. Using terratest should insure that the new applications of your Terraform code continue to work. However, I am curious if there are strategies to allow some resources to remain in place while doing the tests with Terratest. This could be more useful to be included as automated tests in pipelines.