DimitrisKouts
DimitrisKouts

Reputation: 341

Terraform optional nested object variable

New to terraform. Using terraform 0.12. I am trying to terraformize our Cloudflare settings.

Need to create multiple resources of the same type (cloudflare provider page_rule resource) and pass values to the resource "template" using config.tfvars.

I've declared a variable of list(object({...})) type.

Need some of the object parameters to be optional, so if the entries are not specified in config.tfvars for some of the list elements, resources are created without them.

I've read about terraform's 0.12 null default variable values, but I am not sure there is a way to specify default value for terraform object parameters. All examples I've seen only specify the type of parameters.

Code example:

variables.tf

variable "example_page_rule"{
      type = list(object({
            cache_level = string,
            ssl = string,
            target = string    
      }))   
}

main.tf

resource "cloudflare_page_rule" "page_rule" {
        count = length(var.example_page_rule)
    cache_level = var.example_page_rule[count.index].cache_level
    ssl = var.example_page_rule[count.index].ssl
    target = var.example_page_rule[count.index].target
}

config.tfvars

page_rules = [
{
   target = "www.target-url.com",
   ssl = "flexible",
   cache_level = "simplified",
},

{
   target = "www.target-url.com",
   cache_level = "simplified"
}
]

When trying to plan using the above configuration error occurs: "ssl" value is required.

If I change the config.tfvars to the following, all work as expected config.tfvars, but I'd like to avoid entering null values if possibe.

page_rules = [
{
   target = "www.target-url.com",
   ssl = "flexible",
   cache_level = "simplified",
},

{
   target = "www.target-url.com",
   ssl = null,
   cache_level = "simplified"
}
]

Upvotes: 24

Views: 43111

Answers (3)

jandi
jandi

Reputation: 955

Since Terraform 1.3 (released 2022-09-21) there is stable support for optional object attributes:

variable "object_variable" {
  type = object({
    attr1 = number                # a required attribute
    attr2 = optional(number)      # an optional attribute (default = null)
    attr3 = optional(number, 127) # an optional attribute with default value
  })
}

See also https://www.terraform.io/language/expressions/type-constraints#optional-object-type-attributes.


Terraform 0.14 - 1.2 via experiment module_variable_optional_attrs:

Please take a note that this experiment and the documentation about it was removed in v1.3.0 and is no longer usable. If you are coming from the experiment in older versions, the same variable would look like this.

variable "object_variable" {
  type = object({
    attr1 = number                # a required attribute
    attr2 = optional(number)      # an optional attribute (default = null)
    attr3 = optional(number)      # an optional attribute with default value

  })
  default = [
      {
          attr3 = 127
      }
  ]
}

Upvotes: 21

cyberz
cyberz

Reputation: 924

Since terraform 0.14 there is an experiment that allows for optional types, for example:

variable "example_page_rule"{
      type = list(object({
            cache_level = string,
            ssl = optional(string),
            target = string    
      }))   
}

By using optional you could then skip the null values as follows:

page_rules = [
  {
    target = "www.target-url.com",
    cache_level = "simplified"
  }
]

Note that the feature is experimental, so it might change and break your tf files with future terraform versions.

Upvotes: 4

Sean Linguine
Sean Linguine

Reputation: 459

This is a feature request and is being tracked here: https://github.com/hashicorp/terraform/issues/19898. Follow that link and give a :+1: (thumbs up emoji) on the original post so their dev team prioritizes it.

Upvotes: 7

Related Questions