Have optional sub-variables in required Terraform variable
I have created a module corresponding to the Azure Firewall Network Rule Collection. The module looks like this:
resource "azurerm_firewall_network_rule_collection" "fwnrc" {
name = "fwnrc-${var.name}"
resource_group_name = var.resource_group_name
azure_firewall_name = var.azure_firewall_name
priority = var.priority
action = var.action
dynamic "rule" {
for_each = var.rule != null ? [true] : []
content {
name = var.rule.name
description = var.rule.description
source_addresses = var.rule.source_addresses
source_ip_groups = var.rule.source_ip_groups
destination_addresses = var.rule.destination_addresses
destination_ip_groups = var.rule.destination_ip_groups
destination_fqdns = var.rule.destination_fqdns
destination_ports = var.rule.destination_ports
protocols = var.rule.protocols
}
}
}
The section of interest right now is the dynamic "rule"
, which has a corresponding variable defined like this:
variable "rule" {
type = object({
name = string
description = string
source_addresses = list(string)
source_ip_groups = list(string)
destination_addresses = list(string)
destination_ip_groups = list(string)
destination_fqdns = list(string)
destination_ports = list(string)
protocols = list(string)
})
}
I know that it is possible to make the rule
variable "Optional" by setting its default value to null
. I want to go one step deeper and make the sub-variables* optional/required. For instance, in the resource documentation it is written that one must specify either *_addresses
or *_ip_groups
. The docs also says destination_fqdns
is optional.
* Is there an actual name for these?
Since the rule
variable is required by my module I get an error if I do not give explicit values to all sub-variables. My solution for now is to do the following:
module "firewall_network_rule_collection" {
source = "/path/to/module"
name = "fwrc"
azure_firewall_name = "afw"
resource_group_name = "rg"
priority = 110
action = "Allow"
rule = {
description = "rule"
name = "rule"
source_addresses = ["*"]
source_ip_groups = null
destination_ports = ["*"]
destination_addresses = [
"AzureContainerRegistry",
"MicrosoftContainerRegistry",
"AzureActiveDirectory"
]
destination_fqdns = null
destination_ip_groups = null
protocols = ["Any"]
}
}
Note the null
values. Can I get rid of these somehow?
--
I am using the following provider settings:
terraform {
required_version = ">=1.0.11"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=2.90.0"
}
}
}
Solution 1:
The experimental "optional" object type is currently available if one opts in.
Add the following to your module:
terraform {
experiments = [module_variable_optional_attrs]
}
This allows the following:
variable "rule" {
type = object({
name = string
description = optional(string)
source_addresses = optional(list(string))
source_ip_groups = optional(list(string))
destination_addresses = optional(list(string))
destination_ip_groups = optional(list(string))
destination_fqdns = optional(list(string))
destination_ports = optional(list(string))
protocols = optional(list(string))
})
}
Hopefully this feature makes it to a fully supported part of the next release.