How to Structure Your Terraform Code

Terraform represents a robust tool that automates codebase management by creating a private, version-controlled repository and configuring source control systems like Git to ensure synchronization. This article will elucidate the optimal approaches for setting up and utilizing Terraform in conjunction with Git.

By adhering to these guidelines, you will establish a folder structure that facilitates code management, rendering it more accessible while enhancing team productivity.

Why Structure Your Code?

Establishing a standardized structure for your code fosters cohesion, improves readability, and simplifies code creation. Commands remain consistent throughout your codebase. For instance, initializing a development repository can be accomplished using the same command each time:

terraform init --backend-conf=./config/dev/backend.conf
terraform init --backend-conf=./config/test/backend.conf
terraform init --backend-conf=./config/prod/backend.conf

It’s the same with var files.

terraform apply --var-file=./config/dev/vars.tfvars
terraform apply --var-file=./config/test/vars.tfvars
terraform apply --var-file=./config/prod/vars.tfvars

It makes everything much easier when using CI/CD tooling like Jenkins.

Tree Structure

Within this post, we will delve into the importance of maintaining a directory tree structure along with the associated best practices. Additionally, we will provide a helpful diagram illustrating the directory tree to illustrate our points effectively.

By employing a directory tree structure, you can easily locate and access the necessary files and folders. Furthermore, this structure facilitates efficient file and folder management. By adhering to best practices, you can establish a clean and organized directory tree.

.

├── .pre-commit-config.yaml
├── .terraform-docs.yml
├── .gitignore
├── jenkinsfile
├── README.md
├── bitbucket-pipelines.yml
└── tf
├── README.md
├── config
│   ├── dev
│   │   ├── backend.conf
│   │   └── vars.tfvars
│   ├── prod
│   │   ├── backend.conf
│   │   └── vars.tfvars
│   └── test
│   ├── backend.conf
│   └── vars.tfvars
├── main.tf
├── .terraform-version
├── .terraform.lock.hcl
├── outputs.tf
├── providers.tf
├── variables.tf
├── modules
   └── module-1
   └── README.md


Tree Structure Breakdown

.terraform-versionUsed by tfenv to set Terraform version automatically.
Jenkins picks up this file to select the version
.terraform.lock.hclUsed to lock versions of specific providers within Terraform; to upgrade this, use the Terraform init -upgrade command. More information available at Hashicorps Terraform Website
configper environment directory for the backend.conf & vars.tfvars
backend.confUsed by Jenkins to define specific terraform backends
vars.tfvarsenvironment-specific variable values
.pre-commit-config.yaml & .terraform-docs.yamlUsed for terraform documentation within README.md files
JenkinsfileUsed by Jenkins to specify a branch
Modules FolderAll code should be modularized, and the main.tf file should reference each module. This keeps the code clean and portable.
Outputs.tfOutput values make information about your infrastructure available on the command line and can expose information for other Terraform configurations to use. Output values are similar to return values in programming languages.

Module Versioning

When using Terraform, tracking which versions of your modules you are using is essential. This is especially important when upgrading or using modules in a collaborative environment.

“When using Terraform, the version of a module can be determined by the version number in the themodule’ss filename. For example, the terraform module” aws-ec” has a version number of”1.5.0″. “When using Terraform, the version of a module can be determined by the version number in the module’s filename. For example, the terraform module “aws-ec2” has a version number of “1.5.0”.

When using Terraform, tracking which versions of your modules you are using is important. This is especially important when upgrading or using modules in a collaborative environment.

v1.0.0 would be the first user-ready version of a module.

v1.0.0 to v1.0.1 would be for a bug fix

v1.0.0 to v1.2.0 would be for new features, with no breaking changes

v1.0.0 to v2.0.0 would be for new features, with breaking changes

A breaking change forces people using the module to make changes even if they’re not using the new features.


For Ansible Roles, versioning has to be in a semantic versioning format, which means it cannot start with a v like the above example.


Elsewhere On TurboGeek:  AWS Well-Architected Framework

Richard.Bailey

Richard Bailey, a seasoned tech enthusiast, combines a passion for innovation with a knack for simplifying complex concepts. With over a decade in the industry, he's pioneered transformative solutions, blending creativity with technical prowess. An avid writer, Richard's articles resonate with readers, offering insightful perspectives that bridge the gap between technology and everyday life. His commitment to excellence and tireless pursuit of knowledge continues to inspire and shape the tech landscape.

You may also like...

1 Response

  1. 28/06/2024

    […] If you want to learn more about the core command lists above – check out this page on my site. […]

Leave a Reply

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

Translate »