Object attribute defaults on terraform - hello simplicity

Until now i've mostly been using the "configurable defaults" pattern to expose complex configurations to uses of my terraform code (https://blog.nuvotex.de/default-values-on-terraform-objects/).

At some point in time I felt that this is still too much code that also has some downsides under certain situations (an example is deepmerge and the "null value" problen that unsets nested default objects).

Object attribute defaults to the rescue!

A rather simple yet powerful way is to make use of optional attribute defaults (terraform 1.3+). An example for such a variable is shown here:

variable "system_management" {
  type = object({
    configure = bool
    certificates = optional(object({
      ca = optional(object({
        name     = optional(string, "system-pki-ca")
        lifetime = optional(number, 3650)
        keysize  = optional(string, "secp384r1")
      }), {})
      services = optional(object({
        name     = optional(string, "system-tls-cert")
        lifetime = optional(number, 3650)
        keysize  = optional(string, "secp384r1")
      }), {})
    }), {})
    services = optional(object({
      telnet = optional(object({
        port              = optional(number, 23)
        protocol          = optional(string, "tcp")
        enabled           = optional(bool, false)
        allowed_addresses = optional(list(string), ["127.0.0.0/8"])
      }), {})
      ssh = optional(object({
        port              = optional(number, 22)
        protocol          = optional(string, "tcp")
        enabled           = optional(bool, true)
        allowed_addresses = optional(list(string), ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"])
      }), {})
      www = optional(object({
        port              = optional(number, 80)
        protocol          = optional(string, "tcp")
        enabled           = optional(bool, false)
        allowed_addresses = optional(list(string), ["127.0.0.0/8"])
      }), {})
      www-ssl = optional(object({
        port              = optional(number, 443)
        protocol          = optional(string, "tcp")
        enabled           = optional(bool, true)
        allowed_addresses = optional(list(string), ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"])
        use_service_cert  = optional(bool)
        tls_version       = optional(string, "only-1.2")
      }), {})
      }), {
      telnet  = {}
      ssh     = {}
      www     = {}
      www-ssl = {}
    })
  })
  default = {
    configure = false
  }
  nullable = false
}

object defaults

What is happening here?

For every object / value we declare the value as optional but still specify a fallback or default. This results in the behavior that terraform will set the default value for us if the attribute is not specified explicitly.

To apply nested defaults easily, we set the default of every nested object to be {} and terraform will kick in and apply the defaults of this object now in turn for us.

Isn't that somewhat awesome? Easy, well defined - stuff that everyone loves :-)