📂 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!