📂 Terraform Directory Structure & Best Practices
🏗️ Recommended Terraform Directory Structure
A well-structured Terraform project improves maintainability, collaboration, and scalability. Below is a recommended directory structure:
📁 terraform-project/
├── 📁 modules/ # Reusable Terraform modules
│ ├── 📁 network/ # Networking-related resources
│ │ ├── main.tf # Resource definitions
│ │ ├── variables.tf # Input variables
│ │ ├── outputs.tf # Output values
│ ├── 📁 compute/ # Compute resources (EC2, VMs, etc.)
│ │ ├── main.tf # Resource definitions
│ │ ├── variables.tf # Input variables
│ │ ├── outputs.tf # Output values
├── 📁 environments/ # Environment-specific configurations
│ ├── 📁 dev/ # Development environment
│ │ ├── main.tf # Root module calling other modules
│ │ ├── variables.tf # Environment-specific variables
│ │ ├── backend.tf # Remote state backend configuration
│ ├── 📁 prod/ # Production environment
│ │ ├── main.tf # Root module calling other modules
│ │ ├── variables.tf # Environment-specific variables
│ │ ├── backend.tf # Remote state backend configuration
├── 📜 .terraform.lock.hcl # Lock file for module versions
├── 📜 terraform.tfvars # Default variable values
├── 📜 provider.tf # Provider configuration (AWS, Azure, GCP)
└── 📜 README.md # Documentation
📜 Organizing Terraform Files
🔹 main.tf
(Infrastructure Definition)
This file contains the main Terraform configuration and resource definitions. Example:
provider "aws" {
region = var.region
}
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
}
🔹 variables.tf
(Input Variables)
Defines configurable parameters for Terraform resources.
variable "region" {
description = "AWS region to deploy resources"
type = string
}
variable "ami_id" {
description = "AMI ID for EC2 instance"
type = string
}
🔹 outputs.tf
(Output Values)
Declares outputs to display useful information after Terraform applies the changes.
output "instance_public_ip" {
description = "Public IP of the EC2 instance"
value = aws_instance.web.public_ip
}
📦 Using Modules for Better Scalability
Modules help structure and reuse Terraform configurations. Below is an example module for an EC2 instance:
modules/compute/main.tf
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
}
modules/compute/variables.tf
variable "ami_id" {}
variable "instance_type" {}
modules/compute/outputs.tf
output "public_ip" {
value = aws_instance.web.public_ip
}
Using the Module in main.tf
module "web_instance" {
source = "../modules/compute"
ami_id = "ami-123456"
instance_type = "t2.micro"
}
☁️ Remote State Storage (S3/Azure Blob)
Terraform state files should be stored remotely to enable collaboration and prevent state corruption.
🔹 AWS S3 Backend
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "env/dev/terraform.tfstate"
region = "us-east-1"
encrypt = true
}
}
🔹 Azure Blob Storage Backend
terraform {
backend "azurerm" {
resource_group_name = "terraform-rg"
storage_account_name = "terraformstorage"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}
🎯 Best Practices
✅ Use modules to promote reusability.
✅ Store state files remotely (S3, Azure Blob).
✅ Implement environment-specific configurations (e.g., dev
, prod
).
✅ Use backend.tf to avoid storing sensitive information in the repo.
✅ Enable versioning and locking for remote state to prevent conflicts.
🔗 References
📌 Terraform Official Documentation
📌 Best Practices Guide
🚀 Happy Terraforming!