
Overview
Terraform is a powerful tool for infrastructure as code (IaC), and one of its key strengths lies in its ability to manage infrastructure across multiple cloud providers and services. As your Terraform configurations grow in complexity, maintaining a scalable, reusable, and maintainable structure becomes crucial.
A well-organized Terraform directory structure not only enhances collaboration but also ensures that your code is easy to manage, test, and extend. In this blog, we’ll dive into the recommended directory structure for Terraform, providing practical guidance to help you create a modular, reusable, and efficient framework.
Why Directory Structure Matters?
As your infrastructure grows, a poor directory structure can lead to:
Difficulty in scaling: Adding new resources becomes cumbersome.
Lack of modularity: Reusing configurations for different environments or projects becomes challenging.
Collaboration issues: It becomes hard for multiple teams to work on the same infrastructure code.
Risk of misconfiguration: Without clear separation of concerns, mistakes are more likely to happen.
A well-structured Terraform project is:
Scalable: Able to grow with your infrastructure needs.
Modular: Facilitates code reuse and sharing.
Clear and understandable: Improves collaboration and readability.
Maintainable: Makes future updates and changes easier.
Recommended Terraform Directory Structure
The following directory structure is designed for both simplicity and scalability. It emphasizes modularization, clear separation of concerns, and the ability to manage multiple environments with ease.
While there is no universal directory structure that suits every organization, based on our experience and feedback from various teams, we have found the following directory structure to be highly effective. However, this structure still has room for improvement. For instance, if we need to reuse the same modules for another application, creating a duplicate directory structure for that application could lead to redundancy. In our upcoming blogs, we will explore ways to refine and optimize this structure further.

Let’s break down each part of this structure and explain how to use it effectively:
modules/ Directory: Modular Reusability
The modules/ directory is where you place reusable components, which can be thought of as building blocks for your infrastructure. Each module represents a logical unit of functionality, such as networking, compute resources, or security policies.
For example:
network/ module: Could define VPC, subnets, and security groups.
compute/ module: Could manage EC2 instances, autoscaling groups, etc.
database/ module: Could handle RDS instances, backups, and other database configurations.
security/ module: Could manage IAM roles, policies, and security groups.
Each module is independent and reusable across different environments or even different projects. The benefit of using modules is that you can write the configuration once, and reuse it across multiple environments (e.g., dev, staging, production), making your code more DRY (Don’t Repeat Yourself).
Example of a module (network/main.tf):
resource "aws_vpc" "default" {
cidr_block = var.cidr_block
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_subnet" "default" {
vpc_id = aws_vpc.main.id
cidr_block = var.subnet_cidr
availability_zone = var.availability_zone
map_public_ip_on_launch = true
}
Each module should also include:
A variables.tf file to define input variables.
An outputs.tf file to define the outputs that other parts of your code may depend on.
environments/ Directory: Environment-specific Configurations
The environments/ directory is where you define your specific environment configurations (e.g., development, staging, production). This directory contains the actual Terraform configuration files that will be applied to your environments.
For example, the dev/, staging/, and production/ subdirectories each contain the environment-specific configuration files:
main.tf: The main entry point for Terraform configurations, where you define the resources.
variables.tf: Defines environment-specific variables that may override default values from modules.
outputs.tf: Specifies the outputs that Terraform should display after an apply.
terraform.tfvars: Stores environment-specific variable values.
This structure ensures that different environments can share the same modules, but have their own specific configurations (such as different instance sizes, VPC CIDR blocks, etc.).
Example of environment-specific file (dev/main.tf):
module "network" {
source = "../../modules/network"
cidr_block = "192.0.0.0/16"
subnet_cidr = "192.0.1.0/24"
availability_zone = "us-west-2a"
}
module "compute" {
source = "../../modules/compute"
instance_type = "t2.micro"
ami_id = "ami-xxxxxxxx"
}
global/ Directory: Shared Configuration and Providers
The global/ directory contains configuration files that are shared across environments, such as provider configurations, backend configurations, and version constraints. These files are typically not environment-specific and apply to the entire project.
providers.tf: Defines the provider (e.g., AWS, GCP, Azure) and its configuration.
backend.tf: Defines the backend configuration, such as remote state (e.g., S3, Azure Storage).
versions.tf: Specifies the Terraform version and required provider versions.
Example of global configuration (providers.tf):
provider "aws" {
region = var.aws_region
}
provider "aws" {
alias = "secondary"
region = var.secondary_aws_region
}
scripts/ Directory: Helper Scripts
The scripts/ directory is optional but often helpful for tasks that automate your Terraform workflows. For example, you might store shell scripts that set up your local environment, initialize Terraform, or automate testing.
Example of a helper script (scripts/setup.sh):
#!/bin/bash
echo "==> Initializing terraform, please wait..."
terraform init
echo "==> Running terraform apply, please wait..."
terraform apply -var-file=terraform.tfvars
README.md: Project Documentation
Finally, a README.md file at the root of the repository should provide clear documentation for users on how to use your Terraform framework. It should include instructions for initializing, planning, and applying changes to different environments, as well as any other relevant details about the infrastructure setup.
Additional Best Practices
Version Control: Use Git to manage your Terraform code. Ensure that sensitive information (e.g., API keys) is stored securely and not in version-controlled files.
State Management: Always use a remote backend (like AWS S3, Azure Blob Storage, or Terraform Cloud) to store the Terraform state files. This ensures collaboration and prevents state corruption.
Modularization: Break down your code into smaller, reusable modules as much as possible. This improves maintainability and allows teams to work on isolated components.
Use terraform validate and terraform fmt: To ensure code quality and maintain consistency across the project.
Final Thoughts
Choosing the right directory structure for your Terraform projects is crucial for maintaining scalability, flexibility, and ease of collaboration. While the structure we've discussed is a solid foundation based on real-world experience, it's important to remember that cloud infrastructure and development practices are constantly evolving. As your projects grow, there will always be opportunities to refine and improve the structure to better suit your specific needs.
In our future blogs, we'll dive deeper into advanced techniques for optimizing and enhancing this structure, ensuring that your Terraform configurations stay maintainable and reusable. Stay tuned as we continue to explore best practices for building efficient, scalable, and future-proof infrastructure with Terraform!
If you found this blog helpful, don't forget to like, comment, and share your thoughts or experiences! 💬 We’d love to hear your feedback and insights. Follow Ananta Cloud over LinkedIn for more in-depth content, tips, and best practices on cloud infrastructure and Terraform. 🚀 Your engagement helps us create more valuable resources to support your cloud journey!
コメント