To allow omitting keys in live configuration means using module deafult values, I use a workaround like this (this example is for ebs, can be generalized):
(in module variables.tf)
variable "ebs_conf_defaults" {
description = "EBS default configuration (override default inside live configuration)"
type = object({
availability_zone = string
type = string
size = number
encrypted = bool
kms_key_id = string
multi_attach_enabled = bool
snapshot_id = string
outpost_arn = string
iops = number
tags = map(string)
})
default = {
availability_zone = ""
type = "st1"
size = 0
encrypted = false
kms_key_id = ""
multi_attach_enabled = false
snapshot_id = ""
outpost_arn = ""
iops = 0
tags = {}
}
}
variable "ebs_conf" {
description = "EBS configuration (with ebs_conf_defaults to allow default/optional values, see merge in main locals)"
}
(in module main.tf)
### Local definitions
locals {
merged_ebs_conf = merge(var.ebs_conf_defaults, var.ebs_conf)
}
availability_zone = local.merged_ebs_conf.availability_zone
...
(in live config)
locals {
ebs = {
"ebs1" = {
"create" = true
"availability_zone" = "${local.region1}a"
"type" = "gp2"
"size" = 8
"tags" = {
"Environment" = "${local.env_prefix}${local.env}"
}
}
"ebs2" = {
...
}
}
}
module "ebs" {
source = "..."
for_each = {
for key, value in local.ebs:
key => value
if value.create
}
ebs_conf = each.value
}
So i can decouple module upgrade (support for new keys/funcionalities) from live configurations (backwards compatibility) and also allow management o live configuration driven by locals data structures centralized and simple to manage.
This solution works great, but has a limit imposing module specific configuration so I cannot use in live configurations this omit means use module default values logic with e.g standard modules written by other (with separated single variables definition).
There is a solution to keep both benefits ?