A module with too many variables is a copy

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.