Writing Reusable Terraform Modules

A
Author
05 Aug, 2026 1 min read 329 views

A module is a folder of Terraform files used as a building block. Good modules capture your organisation's standards (encryption on, tags set, sensible defaults) so every team gets them for free.

Module layout

modules/static-site/
  main.tf         # resources
  variables.tf    # inputs
  outputs.tf      # outputs
  versions.tf     # required providers
  README.md
# modules/static-site/variables.tf
variable "domain" { type = string }
variable "environment" { type = string }
variable "price_class" {
  type    = string
  default = "PriceClass_200"
}
# modules/static-site/main.tf (excerpt)
resource "aws_s3_bucket" "site" {
  bucket = "${var.domain}-${var.environment}"
}

resource "aws_cloudfront_distribution" "site" {
  price_class = var.price_class
  # ...origins, certificates, cache behaviours
}
# modules/static-site/outputs.tf
output "cdn_domain" { value = aws_cloudfront_distribution.site.domain_name }

Using it

module "marketing_site" {
  source      = "git::https://github.com/acme/terraform-modules.git//static-site?ref=v1.3.0"
  domain      = "www.acme.com"
  environment = "prod"
}

output "marketing_cdn" {
  value = module.marketing_site.cdn_domain
}

Local modules use a path: source = "../modules/static-site". Public modules come from the registry with a version constraint.

Design guidelines

  • Model something meaningful (a "static site", a "service with database"), not a thin wrapper around one resource.
  • Few required inputs, sensible defaults, clear outputs.
  • Don't configure providers inside reusable modules; let the caller pass them.
  • Version modules with tags and pin versions in callers.
  • Keep nesting shallow; modules calling modules calling modules are hard to debug.
Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.