Terraform Structuring Lessons

Overview

Working with Terraform takes some time to get comfortable with. One of the greatest myths in all the examples is the main.tf. Starting a new infrastructure it can make sense to begin with one file an put all resources in there. But after reaching several pages in editor things can easily go down hill from there.

I want to share some lessons learned after taking over larger applications infrastructure project without being able to reach the initial author.

Obstacles For Reading Into Existing Terraform Code

Terraform code for an cloud infrastructure doesn’t make it easy to understand the full picture easily. There is no real beginning or end. Having files containing multiple resources hide all the complexity. Having only one large file to start with is the worst case. Following the dependencies and build a mental overview overloads the mental resource on multiple levels. Simply remembering multiple resources and there dependencies at once is slowing your working memory and increase the error probability.

Remove Obstacles By Refactor First

This learning lead me to conclude that it is takes too much time to try to understand unstructured Terraform code. And it is painful too. Working with a lot of files containing multiple resource definitions I found doing refactoring first instead really worth the effort.

This makes it much easier do get into a infrastructure. Breaking these into atomic files and applying a good file naming convention already helps. You get an understanding of the different parts of the infrastructure just by looking at the files.

Conventions For Readable Readable Code

Don’t

Declare Multiple Resources Into One File

Multiple resource within one file make it complicate to find and understand changes

  • First you must identify the scope of the change, e.g. which resource is affected.
  • Understand the change
  • Finally make sure this affects the correct resource or property

This requires highest concentration and drains a lot of power. This leads to errors and at the same time makes them harder to detect.

Do

Have Atomic Resource Files

Files should contain only one single resource definition. Complex resources can easily fill multiple screens.

  • Changes to files consisting only of one resource definition can be applied and verified with higher confidence.
  • Having atomic resource files make concurrent changes less error prone and prevents or at least reduce number of merge conflicts.

File Name Conventions

Using a good file naming convention you can identify important resource information just by the filename and it’s parent directories. This reduces the information one must remember to understand the structure of the infrastructure.

A good naming convention

  • orders related resources
  • enables to get an high-level overview without reading into the files
  • provides most important information like resource type

Use Modules

The usage of modules can help to adhere to one or multiple of these principles

  • Structure complex infrastructure

Defining an infrastructure component that requires a large number of dependent or interdependent resources is hard. Especially if all resources are in flat file or even a flat structure files. Especially naming gets cumbersome.

  • don’t repeat yourself - DRY

If you create multiple infrastructure components using similar resource definitions it is a good idea to place these into modules.

  • re-use

While implementing multiple infrastructure components finally pattern emerge. These can be used to define modules used by multiple infrastructure components. First within the project. Matured modules can be stored within a separate git repository and referenced by the infrastructure components these.

Closing

This provides an overview about what to take care of to form a high quality IaC project. In further posts I will highlight more details of the different aspects mentioned above. And I plan to create posts sharing details what to take care of while building AWS infrastructure components.

Tags: