2.02 Terraform Configuration Directory & File Conventions
Overview
A Terraform configuration directory is a folder containing one or more .tf files that together define the desired infrastructure state. Terraform loads all .tf files in the directory automatically — there is no need to import or reference them manually.
Abstract
Terraform treats any file with a .tf extension inside the working directory as part of the configuration. While a single file is valid, teams follow a standard naming convention — splitting configuration across main.tf, variables.tf, outputs.tf, and provider.tf — to keep large configurations readable and maintainable.
Why It Matters in Production
- Splitting resources across well-named files makes large configurations easier to navigate and review
- Consistent naming conventions reduce onboarding time for new team members
- Terraform merges all
.tffiles at plan/apply time, so poor organisation leads to hard-to-trace dependency errors - CI/CD pipelines and code review tools benefit from predictable file structure
Key Concepts
| File | Purpose |
|---|---|
main.tf |
Primary configuration file — contains resource definitions |
variables.tf |
Declares input variable blocks |
outputs.tf |
Declares output values exposed after apply |
provider.tf |
Declares provider and required_providers blocks |
*.tf (any name) |
Any file with .tf extension is loaded by Terraform |
Note
These filenames are conventions, not enforced by Terraform. The tooling only requires the .tf extension. However, following the standard convention is strongly recommended for team environments.
How Terraform Loads Files
- Terraform scans the entire working directory for
.tffiles atplanandapplytime - All resource, variable, output, and provider blocks — regardless of which file they are in — are merged into one configuration graph
- Files are not loaded recursively from subdirectories; each directory is its own configuration scope
- Multiple resource blocks of the same type can coexist in one file or be split across multiple files
Example Configuration
Multiple files in one directory
terraform-local-file/
├── main.tf # resource blocks
├── variables.tf # input variables
├── outputs.tf # outputs
└── provider.tf # provider declarations
main.tf with multiple resource blocks
resource "local_file" "pet" {
filename = "/root/pets.txt"
content = "We love pets!"
}
resource "local_file" "cat" {
filename = "/root/cat.txt"
content = "My favorite pet is Mr. Whiskers"
}
Equivalent split across two files
Both approaches produce identical results — Terraform merges them at runtime.
Best Practices
Best Practices
- Use the standard four-file layout (
main.tf,variables.tf,outputs.tf,provider.tf) for any project beyond a quick test. - For large projects, split
main.tfby logical grouping — e.g.network.tf,compute.tf,storage.tf— rather than one monolithic file. - Keep provider declarations in a dedicated
provider.tfso version constraints are easy to locate and update. - Never mix resource definitions and variable declarations in the same file in team projects — reviewers expect them in their conventional locations.
- Use consistent indentation (2 spaces) and run
terraform fmtbefore committing to normalise formatting across all.tffiles.
Security Best Practices
Security
- Never commit
.tfvarsfiles containing secrets (API keys, passwords) to version control — add*.tfvarsto.gitignoreand use a secrets manager or CI environment variables instead. - Avoid hardcoding sensitive values directly in
main.tfresource arguments; usesensitive = truevariables and reference them viavar.name. - Restrict read access to the configuration directory in CI environments — it may contain state references or backend configs with access credentials.
Do and Don't
| ✅ Do | ❌ Don't |
|---|---|
Follow the standard main.tf / variables.tf / outputs.tf / provider.tf layout |
Put everything in one unnamed file for production configs |
Run terraform fmt to auto-format all .tf files |
Mix provider declarations inside main.tf in team projects |
Split large main.tf by resource type (network.tf, compute.tf) |
Create .tf files in subdirectories expecting them to be auto-loaded |
| Keep the directory focused — one environment per directory | Add .terraform/ or *.tfstate to version control |
Common Mistakes
Common Mistakes
- Expecting subdirectory loading: Terraform does not recurse into subdirectories. Place all
.tffiles at the root of the configuration directory or use modules for nested structure. - Duplicate resource names across files: Two resource blocks with the same type and name (e.g.
resource "local_file" "pet"in bothmain.tfandpet.tf) will cause an error — resource names must be unique within a directory. - Renaming files mid-project without checking references: Terraform itself doesn't care about filenames, but team tooling, CI scripts, and documentation often reference
main.tfby name. - Putting outputs in
main.tf: Works, but breaks the convention — reviewers will look inoutputs.tffirst.
Troubleshooting
# Validate all .tf files in the current directory for syntax errors
terraform validate
# Auto-format all .tf files to the canonical style
terraform fmt
# List all .tf files Terraform will load
ls *.tf
# Show the merged configuration graph (useful to verify all files are loaded)
terraform graph
Quick Recap
- Terraform loads all
.tffiles in the working directory — filename does not affect loading, only convention - The standard layout is:
main.tf(resources),variables.tf(inputs),outputs.tf(outputs),provider.tf(providers) - A single
main.tfcan hold multiple resource blocks — both single-file and multi-file approaches are valid - Files in subdirectories are not auto-loaded — use modules for nested configuration
terraform fmtenforces consistent formatting across all files in the directory
Interview / Revision Notes
Revision
- Does Terraform care what
.tffiles are named? No — any file with a.tfextension in the directory is loaded. Names are conventions only. - What are the four standard Terraform filenames?
main.tf,variables.tf,outputs.tf,provider.tf. - Does Terraform load
.tffiles from subdirectories automatically? No — subdirectories require explicit module references. - Can two
.tffiles in the same directory define resources of the same type? Yes, as long as the resource names (labels) are unique. - What command formats
.tffiles?terraform fmt. - What command checks
.tffiles for syntax errors?terraform validate.