How to Structure Terraform Modules for Reusable Infrastructure
To structure
Terraform modules, organize your code into folders with main.tf, variables.tf, and outputs.tf files. Each module should have clear inputs and outputs to be reusable and maintainable across projects.Syntax
A Terraform module is a folder containing configuration files. The main files are:
main.tf: Defines resources.variables.tf: Declares input variables.outputs.tf: Declares outputs to share data.
Modules are called from root configurations using module "name" { source = "path" ... }.
terraform
module "example" { source = "./modules/example" variable1 = "value" }
Example
This example shows a simple module that creates an AWS S3 bucket with input for the bucket name and outputs the bucket ARN.
terraform
/* modules/s3_bucket/main.tf */ resource "aws_s3_bucket" "bucket" { bucket = var.bucket_name acl = "private" } /* modules/s3_bucket/variables.tf */ variable "bucket_name" { description = "The name of the S3 bucket" type = string } /* modules/s3_bucket/outputs.tf */ output "bucket_arn" { value = aws_s3_bucket.bucket.arn } /* root/main.tf */ provider "aws" { region = "us-east-1" } module "my_bucket" { source = "./modules/s3_bucket" bucket_name = "my-unique-bucket-12345" } output "bucket_arn" { value = module.my_bucket.bucket_arn }
Output
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
bucket_arn = arn:aws:s3:::my-unique-bucket-12345
Common Pitfalls
Common mistakes when structuring Terraform modules include:
- Not separating variables and outputs into their own files, making code hard to read.
- Hardcoding values inside modules instead of using variables, reducing reusability.
- Not using
outputsto expose useful information from modules. - Using relative paths incorrectly in
sourcewhen calling modules.
terraform
/* Wrong: hardcoded bucket name inside module */ resource "aws_s3_bucket" "bucket" { bucket = "fixed-name" acl = "private" } /* Right: use variable for bucket name */ variable "bucket_name" { type = string } resource "aws_s3_bucket" "bucket" { bucket = var.bucket_name acl = "private" }
Quick Reference
Tips for structuring Terraform modules:
- Use separate files:
main.tf,variables.tf,outputs.tf. - Keep modules focused on a single responsibility.
- Use clear variable names and provide descriptions.
- Always output useful information for other modules or root.
- Test modules independently before integrating.
Key Takeaways
Organize Terraform modules with main.tf, variables.tf, and outputs.tf files for clarity.
Use variables for inputs and outputs to make modules reusable and flexible.
Avoid hardcoding values inside modules to keep them adaptable.
Test modules separately to ensure they work before using them in larger projects.
Keep modules focused on one task to simplify maintenance and reuse.