Terraform require only specific values in object

Consider the following Example:

variable "myvar" {
  type = object({
    key1 = string
    key2 = string
    key3 = string
  })
}

Is it possible to define an object which requires the structure defined above, but additionally allows to specify arbitrary keys for input? I don’t want to use optional() for the values here, since the additional keys are not known. All specified keys should then be applied using merge(var.myvar) on a resource.

Hi @Rai,

What you want to do here is not possible in the Terraform language, because it mixes ideas from two different kinds of type:

  • Object types have a fixed set of attributes decided by the module author. Each attribute may have a different type.
  • Map types represent any number of values of the same type that are each identified by arbitrary keys. The keys are therefore decided by the caller of your module, rather than by you.

If you just want an arbitrary set of key/value pairs then map(string) would be the most appropriate type constraint. You could optionally combine that with a custom validation rule which requires particular keys to be present for the argument to be valid:

variable "myvar" {
  type = map(string)

  validation {
    condition = contains(keys(var.myvar), "key1")
    error_message = "The key \"key1\" is required."
  }
  validation {
    condition = contains(keys(var.myvar), "key2")
    error_message = "The key \"key2\" is required."
  }
  validation {
    condition = contains(keys(var.myvar), "key3")
    error_message = "The key \"key3\" is required."
  }
}

The above will allow arbitrary map keys during type conversion but will then check afterwards for the three required keys and raise an error if they aren’t set.

Amazing solution @apparentlymart
Appreciate your help!