Five (5) Important Things to Know About Organizing Terraform Code
One of the most common questions I see popup time and time again— and something I see debated endlessly on Reddit— is how to structure Terraform code. Should files be broken up by service or logical grouping? Should folders mirror publicly published modules like Azure Landing Zone architecture? Is there a “right” way?
Terraform module design is a deep and nuanced topic, and to be honest, I’m writing an entire book about it. But even outside the weeds of module composition and abstraction, there are a handful of important principles I’ve learned the hard way that can help you write Terraform code that is predictable, maintainable, and easy for your future self (and your team) to work with.
Here are 7 important things to know when organizing Terraform code, especially when working in Azure environments.
1. Use Multiple Files in a Single Module
It’s completely valid — and recommended — to break a Terraform module into multiple .tf files. Terraform doesn’t care what you name them or what order they appear in the directory. All files in a given directory are loaded into the same module context.
So don’t dump everything into a single main.tf. Break it up.
Common patterns include splitting by:
- Resource type (vnet.tf, storage.tf, vmss.tf)
- Logical grouping (network.tf, compute.tf, identity.tf)
- Functional domain (bastion.tf, private_endpoints.tf, monitoring.tf)
There’s no one correct approach, so…
“Pick your poison. Whatever feels right and makes sense to you.”
Just make sure the structure is consistent and obvious to other developers reading your code. Aim for clarity over cleverness. You’re not impressing anyone with stgaccs.tf. Just call it storage.tf and let people breathe.
As always, strike balance, don’t try to load up with an overly aggressive naming convention — let it emerge naturally and organically.
2. Avoid Cryptic or Overly Clever Naming Conventions
Resist the temptation to use shorthand names, acronyms, or numeric prefixes like 01_network.tf, 02_compute.tf.
“This gives a false impression that the file is processed in a specific order. As we know, Terraform builds its own plan based on it’s own dependency graph.”
Terraform’s execution plan is determined by resource relationships, not file order. Naming files with numeric prefixes might make sense for a Bash script, but it introduces potentially confusion in Terraform projects.
3. Align with Public Modules When It Adds Clarity
There are popular public modules and even officially cannonized by some authority — be it HashiCorp or a cloud provider like Microsoft. Azure Verified Modules are a good example. Azure Landing Zone model separates environments into Platform (Connectivity, Management, Identity) and Application landing zones. It’s a great architectural framework — but don’t feel like your file or folder structure needs to mirror it exactly.
You might have a top-level folder structure that separates platform and application scopes, like this:
/platform
- /identity
- /networking
- /management
/application
- /product-api
- /data-platform
But within each module, you’re better off sticking to standard Terraform best practices: small, focused, self-contained units of infrastructure with clear interfaces.
“I would encourage you to follow sound software development practices that emphasize maintainability, readability and predictability.”
Use public modules internal structure and model for guidance, not gospel.
4. Use a Consistent Naming Convention for Modules and Outputs
Whether you’re writing root modules or reusable ones, consistent naming matters. Pick a pattern and stick to it. Some examples:
- Use underscores for outputs: vnet_id, storage_account_name
- Keep folder names lowercase and dash-separated: regional-deployment, aks-cluster
Consistency helps with code scanning, automation, and onboarding new contributors. Terraform code isn’t parsed by humans line by line — people scan it. Make scanning easy.
5. Start Simple. Let Complexity Emerge Gradually
In the beginning, don’t over-engineer. Start with a single module, maybe a single file if that’s all you need. As your infrastructure grows, you’ll start to feel the natural pressure points: too many resources in one file, duplication across environments, shared infrastructure that needs to be isolated.
Let those pain points drive the evolution of your structure.
“Don’t try to overthink the naming conventions or structure up front. Let practicality guide you.”
Terraform rewards iteration. Don’t be afraid to refactor.
Final Thoughts
Organizing Terraform code is one of those things that seems simple until it isn’t. There’s no perfect file structure, no universally blessed naming scheme. But there are principles that will keep you sane as your codebase grows:
- Be clear.
- Be consistent.
- Don’t be clever at the cost of comprehension.
Terraform isn’t application code. It’s infrastructure modeling and configuration. Prioritize human readability and let Terraform’s dependency graph do the hard work.
Whether you’re building a new app or services or laying down the foundation for your enterprise’s cloud adoption, these principles will help you write Terraform code that doesn’t just work — but works well for teams.