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.
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.
│ ├── dev
│ │ ├── backend.conf
│ │ └── vars.tfvars
│ ├── prod
│ │ ├── backend.conf
│ │ └── vars.tfvars
│ └── test
│ ├── backend.conf
│ └── vars.tfvars
Tree Structure Breakdown
|.terraform-version||Used by tfenv to set Terraform version automatically.|
Jenkins picks up this file to select the version
|.terraform.lock.hcl||Used to lock versions of specific providers within Terraform; to upgrade this, use the Terraform init -upgrade command. More information available at Hashicorps Terraform Website|
|config||per environment directory for the backend.conf & vars.tfvars|
|backend.conf||Used by Jenkins to define specific terraform backends|
|vars.tfvars||environment-specific variable values|
|.pre-commit-config.yaml & .terraform-docs.yaml||Used for terraform documentation within README.md files|
|Jenkinsfile||Used by Jenkins to specify a branch|
|Modules Folder||All code should be modularized, and the main.tf file should reference each module. This keeps the code clean and portable.|
|Outputs.tf||Output 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.|
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.