A Guide to Terraform Pre-Commit Hooks

We (like everyone else) want to be able to ship easy to read code in a way that’s fast, maintainable, and free of errors. As our operations grow, so does the amount of infrastructure we manage and the size of the teams involved. At Spokeo, we have gone from AWS GUI -> shell scripts aws-cli calls to create instances -> using Terraform, Infrastructure as code. 

As operations teams grow, ground rules on code styles and review can become tribal knowledge that is hard to communicate or standardize. The whole argument of tabs vs spaces, heredoc vs codified comes into play as many engineers already have a predisposition to one or the other. Using auto formatters like Terraform pre-commit hooks relieves code reviewers of having to scrutinize these details while easily creating uniform code that anybody can clearly read. This is already a fairly common development practice that can be leveraged with infrastructure as code.

General Guidelines

Homogenized Formatting

We implement homogenized formatting in Terraform by setting up a pre-commit hook to run terraform fmt to ensure that the “tf” files conform to formatting standards. Pre-commit tells Terraform to automatically implement standardized formatting. This removes the annoying task of lining up the “=”.

Basic Linting

This attempts to catch all the blatantly wrong or “fat fingered” errors.  There is also an attempt to catch provider specific errors such as wrong instance types for AWS that don’t typically reveal themselves in a terraform plan and terraform validate.  

Basic Security Checks

We’ve implemented linters that will check for basic security issues such as ensuring that buckets are not public and instances are not open to the world. We also implemented a feature that allows us to tag on a line-by-line basis in order to be able to create exemptions for specific use cases. 

Our Configuration

We use the boilerplate pre-commit hook setup which runs before every git commit -m.  This is a sample of our configuration:

This is what it looks like when it runs:

We also have jenkins setup with Git hooks to monitor all pull requests in order to ensure that the pull request meets all standards:

Where to go from here

Terraform pre-commit hooks have been a great addition to our workflow. They make our code more uniform and help us easily spot the small trivial issues that might slip by. However, things are far from perfect. One current shortcoming is that we run “terraform apply” from our laptops instead of a server. Eventually we would like to get to a point where infrastructure is deployed via continuous integration. This will help mitigate the “someone didn’t commit their changes” issue. We want to get to a point where developers have a self-service infrastructure option, which will empower them to make sure they have all the tools they need to ship code faster.