Writing Reusable Terraform Modules
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.