MorNando
MorNando

Reputation: 89

Terraform Conditional Content Block Inside Resource

How do I make ip_configuration optional to turn the below:

resource "azurerm_firewall" "example" {
  name                = "testfirewall"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                 = "configuration"
    subnet_id            = azurerm_subnet.example.id
    public_ip_address_id = azurerm_public_ip.example.id
  }
}

In to something that OPTIONALLY accepts values in this:

variable "ip_configuration" {
    type = object({
        name = string // Specifies the name of the IP Configuration.
        subnet_id = string // Reference to the subnet associated with the IP Configuration.
        public_ip_address_id = string // The ID of the Public IP Address associated with the firewall.
    })

    description = "(Optional) An ip_configuration block as documented"

    default = null
}

I was looking at dynamic blocks, lookups and try expressions but nothing seems to work. Can anyone help? I have spent days on it trying to figure it out

Edit: There maybe a neater way to do it, but I have found something that works. If someone can improve on this that would be great, but thanks for those who have replied.

subnet_id should only appear in the first ip_configuration which is why I have decided to use the numbering system on the key.

resource "azurerm_firewall" "example" {
  name                = "testfirewall"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  dynamic "ip_configuration" {
    for_each = var.ip_configuration
    iterator = ip

    content {
      name                 = ip.value["name"]
      subnet_id            = ip.key == "0" ? ip.value["subnet_id"] : null
      public_ip_address_id = ip.value["public_ip_address_id"]
    }
  }
}

variable "ip_configuration" {
    type = map

    description = <<-EOT
    (Optional) An ip_configuration block is nested maps with 0, 1, 2, 3 as the name of the map as documented below:

    name = string // Specifies the name of the IP Configuration.
    public_ip_address_id = string // The ID of the Public IP Address associated with the firewall.
    subnet_id = string // Reference to the subnet associated with the IP Configuration. The Subnet used for the Firewall must have the name AzureFirewallSubnet and the subnet mask must be at least a /26.
    
    NOTE: Only the first map (with a key of 0) should have a subnet_id property.

    EXAMPLE LAYOUT:
    {
        "0" = {
            name = "first_pip_configuration"
            public_ip_address_id = azurerm_public_ip.firstpip.id
            subnet_id = azurerm_subnet.example.id
        },
        "1" = {
            name = "second_pip_configuration"
            public_ip_address_id = azurerm_public_ip.secondpip.id
        },
        "2" = {
            name = "third_pip_configuration"
            public_ip_address_id = azurerm_public_ip.thirdpip.id
        }
    }
    EOT

    default = {}
}


Upvotes: 1

Views: 3811

Answers (1)

MorNando
MorNando

Reputation: 89

There maybe a neater way to do it, but I have found something that works. If someone can improve on this that would be great, but thanks for those who have replied.

subnet_id should only appear in the first ip_configuration which is why I have decided to use the numbering system on the key.

resource "azurerm_firewall" "example" {
  name                = "testfirewall"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  dynamic "ip_configuration" {
    for_each = var.ip_configuration
    iterator = ip

    content {
      name                 = ip.value["name"]
      subnet_id            = ip.key == "0" ? ip.value["subnet_id"] : null
      public_ip_address_id = ip.value["public_ip_address_id"]
    }
  }
}

variable "ip_configuration" {
    type = map

    description = <<-EOT
    (Optional) An ip_configuration block is nested maps with 0, 1, 2, 3 as the name of the map as documented below:

    name = string // Specifies the name of the IP Configuration.
    public_ip_address_id = string // The ID of the Public IP Address associated with the firewall.
    subnet_id = string // Reference to the subnet associated with the IP Configuration. The Subnet used for the Firewall must have the name AzureFirewallSubnet and the subnet mask must be at least a /26.
    
    NOTE: Only the first map (with a key of 0) should have a subnet_id property.

    EXAMPLE LAYOUT:
    {
        "0" = {
            name = "first_pip_configuration"
            public_ip_address_id = azurerm_public_ip.firstpip.id
            subnet_id = azurerm_subnet.example.id
        },
        "1" = {
            name = "second_pip_configuration"
            public_ip_address_id = azurerm_public_ip.secondpip.id
        },
        "2" = {
            name = "third_pip_configuration"
            public_ip_address_id = azurerm_public_ip.thirdpip.id
        }
    }
    EOT

    default = {}
}


Upvotes: 1

Related Questions