A module exposing every attribute of the resources it wraps has not abstracted anything — it is the same configuration with an extra indirection.
# eleven variables, all pass-through
module "database" {
source = "./modules/rds"
engine_version = "8.0.23"
instance_class = "db.t3.medium"
allocated_storage = 100
backup_window = "03:00-04:00"
# ... seven more
}
# what a module should offer
module "database" {
source = "./modules/rds"
name = "shop"
size = "medium" # the module decides what that means
}
The test is whether the module encodes a decision. A module that says a medium database means this instance class, this backup window and these parameter group settings is worth having, because those decisions are now made once. A module that forwards eleven variables makes every caller make them again and adds a layer to read through. The pressure to add the twelfth variable is constant and is the thing to resist.