Appleoddity
Appleoddity

Reputation: 1181

Proper way to declare and pass variables from tfvars to root to module in Terraform / OpenTofu without duplicating code

What is the correct way to pass variables from the environment or .tfvars into the root module and on to sub-modules? I know this question is borderline opinion, but I feel there has to be a clear, best-practice on this.

Say, I have the following "complex" object defined in .tfvars:

example = [
  {
    name = "example1"
    size = {
      height = 10
      length = 20
    }
  },
  {
    name = "example2"
    size = {
      height = 30
      length = 40
    }
  }
]

Now, should I declare this complex data type, validations, and defaults in the main.tf? The module.tf? Or both?

For example, this could be the variable declaration:

variable "example" {
  type = list(object({
    name = string
    size = {
      height = number
      length = number
    }
  }))
  nullable = false
  description = "Example complex object"
  validation {
    condition = example.size.height > 5
    error_message = "Your height is expected to be greater than 5."
  }
}

Now, it doesn't make sense to me that I would declare this level of complexity and checks in the main.tf AND in the module.tf and duplicate code. Especially considering the module.tf may be re-used in other projects.

Instead, I could declare something like this in the main.tf:

variable "example" {
  type = list(object())
  nullable = false
  description = "Example complex object."
}

and let the module.tf actually validate the variable.

What is the correct way to do this?

Upvotes: 0

Views: 56

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17654

After replying in the comments I noticed that your example has a few issues:

  • The size = { is not valid syntax
  • The validation for a list will need a loop

working code:

variable "example" {
  description = "Example complex object"

  type = list(object({
    name = string
    size = object({
      height = number
      length = number
    })
  }))

  validation {
    condition = alltrue([
      for v in var.example : v.size.height > 5
    ])
    error_message = "Your height is expected to be greater than 5."
  }
}

My answer does not address your main concern of reusability, that is a feature that hopefully will be added to terraform in the near future

Upvotes: 0

Related Questions