Terraform Insights - Part 1 : How to Structure Terraform for Large-Scale Projects
Workspaces vs. Folders: Which One Should You Choose?

When working with Terraform in real-world environments, it’s not just about writing .tf files, it’s about understanding the small details that make a big difference in reliability, scalability, and maintainability.
In this blog, we’ll explore some important Terraform insights and nitty-gritties that are extremely useful for day to day work. These are the kind of concepts that not only make you better at Terraform but also give you an edge in technical discussions and interviews.
The blog is structured in a simple and practical way. Each topic will cover:
What it is – A clear explanation of the concept
Why and Where it is used – Real-world scenarios where it applies
How to use it – Practical usage with Terraform
Example – So you can relate and apply it immediately
This approach ensures that you don’t just understand the concept, you know exactly how to use it.
Let’s get started 🚀
How do we structure the terraform code for large project
One of the most common questions we encounter is: “How do we structure Terraform code for a large project?”
This becomes even more critical when working on a greenfield setup, where everything is being built from scratch. The decisions you make at this stage will directly impact how well your infrastructure scales, how easy it is to maintain, and how effectively teams can collaborate.
So, how do we design a Terraform project that not only works today but also scales seamlessly in the future? Let’s dive deeper into this.
What it is ?
Before diving into how to structure a Terraform project, let’s first get the basics clear: What exactly are we structuring? What are we really talking about here?
Every Terraform project is made up of a set of core files and components. The real challenge is not creating these files, it’s about organizing them in a way that scales with your infrastructure.
Core Components in a Terraform Project
Modules: Modules are the building blocks of any Terraform project. It helps you to Reuse Code, Maintain Consistency and Avoid Duplication. A typical module consists of:
main.tf→ Defines the resourcesvariables.tf→ Input variables.outputs.tf→ Exposes valuesprovider.tf→ Provider configurationversions.tf→ Terraform & provider version constraintsdata.tf→ Data sourcesbackend.tf→ Remote state configuration (sometimes kept separate mostly added with versions.tf)
State File Management: Terraform maintains a state file to track the current state of your infrastructure. Proper state management is critical for Preventing Conflicts, Ensuring Consistency and Enabling team collaboration.
Key considerations:
Where is the state stored? (local vs remote),
How is state locking handled?
How do multiple users safely interact with it?
⚠️ Pain Point: Large State File Slowing Down Terraform: When all resources are managed in a single Terraform state file, it grows significantly in size and slows down deployments because Terraform must evaluate the entire state during every run; to avoid this, it’s a best practice to split state files logically—either by resource type or architectural design to improve performance, scalability, and maintainability.
Multi-Environment & Multi-Region Deployment: Real-world infrastructure is rarely single-environment. This involves Structuring Folders properly, Passing Environment specific variables, Managing isolated State files
- You need to manage deployments across Environments (dev, stag and prod etc..) and across region (us-east-1, eu-west-1 etc..)
Input Variables & Defaults Management: Variables make your Terraform code dynamic and reusable. Doing a right setup here will allow our code base to work across different region and enviornment
Things to Consider
Defining clear input variables
Setting sensible defaults
Overriding values per environment
So, when we talk about structuring Terraform, we are essentially talking about how we organize these building blocks effectively.
In Simple Terms
Structuring Terraform is about:
Organizing modules, state, variables, and environments in a way that your code scales along with your infrastructure without breaking performance, security, or maintainability.
Now we understand the what part let's discuss the why part.
Why?
Let's talk about why this is needed, As your infrastructure grows, your Terraform code should be able to:
Handle complexity without becoming messy: As more components (infra resource) are added, the codebase should remain clean, well organized, and easy to debug or navigate.
Support multiple environments and regions: The same codebase should support deployments across different environments (dev, staging, prod) and regions with minimal or no changes to the core logic.
Maintain performance and security: Execution performance and security standards should remain consistent or improve as the infrastructure scales, without degradation.
Enable easy collaboration across teams: As infrastructure grows, more team members will contribute. The code should be structured in a way that enables seamless collaboration and reduces conflicts.
By arranging them in this way helps you to grow your IaC seamlessly as your infrastructure grows.
How ?
When starting a greenfield Infrastructure as Code (IaC) project, there are multiple ways to structure and manage your infrastructure. Choosing the right approach early helps improve scalability, maintainability, collaboration, and operational efficiency as the infrastructure grows.
In this section, we will discuss two commonly used approaches for organizing Terraform based IaC projects:
Terraform Workspace Approach
Modular Folder-Based Approach
Terraform Workspace Approach
What is Terraform Workspace?
Terraform Workspaces allow you to manage multiple instances of the same infrastructure configuration using a single Terraform codebase.
Each workspace maintains its own separate state file, enabling you to deploy the same infrastructure into different environments such as:
- Development (
dev), Testing (test), Staging (stage), Production (prod)
Instead of maintaining separate folders or separate state files manually, Terraform automatically isolates the infrastructure state per workspace.
Why Use Terraform Workspaces?
As infrastructure grows, managing multiple environments becomes challenging. Teams often need identical infrastructure across environments with only minor differences such as:
- Instance size, Number of replicas, Database sizing
Terraform Workspaces help reduce duplication by allowing the same code to be reused across environments while keeping the infrastructure states isolated.
This approach improves:
Code reusability
Consistency across environments
Simpler maintenance
Faster onboarding
Where Can Terraform Workspaces Be Used?
Multiple Similar Environments Exist - Dev, Qa, Prod where you will use same infra setup while only minor changes are required
Platform or Shared Services Teams: Teams managing reusable infrastructure templates can deploy the same stack for different customers, regions, or business units.
Temporary or Feature Environments: Useful fof Feature branch testing, Sandbox testing
How Terraform Workspace Works
Consider a hotel where:
The kitchen prepares a common base meal for all guests.
Every guest stays in a separate room.
Guests can customize their food in their own room by adding available ingredients such as:
Pepper
Salt
Sauces
Spices
The chef does not cook completely different meals for every room. Instead, one common meal is prepared and each room customizes it based on individual preferences.
Relating This to Terraform Workspaces
In Terraform:
The main Terraform code acts like the hotel kitchen.
Each workspace acts like a separate room/environment.
The common infrastructure code remains the same for all environments.
Each workspace can customize values such as:
Instance size
Resource count
Naming conventions
Scaling configuration
Environment variables
without changing the core infrastructure code.
How to create workspace and work with that?
To list the available workspace you use:
terraform workspace listTo Create new workspace :
terraform workspace new <workspace name>terraform workspace new devterraform workspace new prod
Switch between workspace:
terraform workspace select dev
In a real-world setup, Terraform Workspaces are commonly used by creating a separate workspace for each environment such as dev, test, and prod. The typical workflow looks like this:
Create and maintain separate workspaces for each environment
Select the required workspace before performing any operation
terraform workspace select devVerify that you are in the correct workspace
terraform workspace showRun Terraform commands, which will apply the infrastructure using the variables and state associated with that workspace
terraform apply
Pros:
Reduced Code Duplication
Easier Maintenance
Faster Environment Creation
Consistency Across Environments
Simplified State Isolation
Cons:
Shared Backend Complexity: All workspaces typically share the same backend configuration. So all the backed files are in same location so you need to create a complex rules to restrict user to access the backend statefiles.
Risk of Human Error: Accidentally applying changes in the wrong workspace can impact production.
Difficult CI/CD Integration at Scale: As the number of environment increases Pipeline management becomes harder, Environment-specific approvals become complex, State access management becomes difficult
Limited Environment Customization: Workspaces work best when environments are nearly identical.
Use Workspaces When
✅ Infrastructure is mostly identical
✅ Environment differences are minimal
✅ Small-to-medium scale projects
✅ Rapid environment provisioning is needed
If that is the case how the other modular folder based approach solve the problem let's discuss that.
Modular Folder-Based Approach
The Modular Folder-Based Approach is a Terraform project structure where infrastructure is organized into:
Reusable Modules
Environment-specific folders
Instead of using a single Terraform configuration for all environments, each environment has its own dedicated folder and configuration while sharing reusable infrastructure modules. This approach separates:
Reusable infrastructure logic
Environment-specific configurations
making the infrastructure easier to scale, maintain, and manage. This is the industry wide popular approach used to manage large projects
Why Use the Modular Folder-Based Approach?
As infrastructure grows, environments usually become different from each other. For example:
Production may require: Multi-region deployment, High Availability, Autoscaling etc which is not needed for Dev
For Dev we can use low cost instances and minimum setup to test the code.
Managing these differences using only Terraform Workspaces can become complicated. The Modular Folder-Based Approach solves this by:
Separating environments completely
Reusing infrastructure components through modules
Allowing each environment to evolve independently
Where Can This Approach Be Used?
As mentioned this is the industry wide popular approach,
Enterprise Infrastructure
Production-Grade Platforms
Multi-Region Deployments
Microservices Platforms
How we Design this approach ?
We will create a folder structure as mentioned below :
terraform/
├── modules/
│ ├── vpc/
│ ├── ec2/
│ ├── rds/
│ └── eks/
│
└── environments/
├── dev/
│ ├── main.tf
│ ├── variables.tf
│ └── terraform.tfvars
│
├── test/
│ ├── main.tf
│ ├── variables.tf
│ └── terraform.tfvars
│
└── prod/
├── main.tf
├── variables.tf
└── terraform.tfvars
How It Works
Modules Directory: Contains reusable infrastructure components. Each module is written once and reused across environments.
Environment Directory: Each environment
Maintains its own Terraform state
Has its own backend configuration
Uses its own variable values
Can independently deploy infrastructure
Pros
One of the major advantages of the Modular Folder-Based Approach is that it helps reduce human error compared to Terraform Workspaces. In the workspace approach, users must manually switch between environments, and in real-world scenarios engineers may accidentally apply changes to the wrong workspace assuming they are already in the correct one. With the folder-based approach, each environment has its own dedicated directory such as
dev,test, andprod, and users must explicitly navigate to the corresponding folder before running Terraform commands. This clear separation between environments greatly reduces the chances of accidental deployments and improves operational safety, especially for production infrastructure.Better Scalability: Works well with Large infrastructure, Multi-team organizations
Reusable Infrastructure Components: Modules reduce duplication while keeping flexibility.
Easier Customization: Each environment can use different modules, different architecture and can scale as per the need
Better Security and Access Control
Easier CI/CD Integration
Cons:
More Folder Management
Slightly More Initial Setup
Risk of Module Over-Engineering
Version Management Complexity
Best Practices
Keep Modules Small and Focused
Maintain Independent State Per Environment
Use Versioned Modules
source = "git::https://github.com/org/vpc-module.git?ref=v1.0.0"
When to Use This Approach
Use the Modular Folder-Based Approach when:
✅ Infrastructure differs across environments
✅ Large-scale systems are involved
✅ Strong isolation is required
✅ Multiple teams manage infrastructure
✅ Enterprise-grade CI/CD pipelines exist
✅ Security boundaries are important
Conclusion
The Modular Folder-Based Approach is one of the most scalable and production-friendly ways to organize Terraform infrastructure.
It provides:
Reusable infrastructure through modules
Strong environment isolation
Better scalability
Easier customization
Safer production deployments
While it introduces slightly more structure and setup effort initially, it becomes significantly easier to manage as infrastructure and teams grow.



