terraformterraform-provider-azure

terraform use a dynamic count to get value from a list


I am trying to use count to get the values from a list, and all the solutions I have found so far error out for my setup. I need to take the existing vnet and split it into x Subnets based upon the number of environments I am building.

locals.tf

locals {
  build_ena_true       = var.build_ena ? 1 : 0
  build_dmz_true       = var.build_dmz ? 1 : 0
  build_bdl_true       = var.build_bdl ? 1 : 0
  azurerm_cidrs = [
    cidrsubnet("10.1.2.0/24", 1, 0),
    cidrsubnet(cidrsubnet("10.1.2.0/24", 1, 1), 1, 0),
    cidrsubnet(cidrsubnet("10.1.2.0/24", 1, 1), 1, 1)
  ]
}

network.tf

resource "azurerm_subnet" "subnet" {
  count                = local.build_ena_true + local.build_dmz_true + local.build_bdl_true
  name                 = "${var.azurerm_resource_prefix}-${local.env_short_name}-snet-${format("%03d", count.index + 1)}"
  resource_group_name  = var.azurerm_net_resource_group
  virtual_network_name = var.azurerm_network_name
  address_prefixes     = local.azurerm_cidrs[count.index]
}

Error Text

│ Error: Incorrect attribute value type
│
│   on network.tf line 21, in resource "azurerm_subnet" "subnet":
│   21:   address_prefixes     = local.azurerm_cidrs[count.index]
│     ├────────────────
│     │ count.index is 0
│     │ local.azurerm_cidrs is tuple with 3 elements
│
│ Inappropriate value for attribute "address_prefixes": list of string required.

I also tried using element with a map instead of a list

locals.tf

locals {
  build_ena_true       = var.build_ena ? 1 : 0
  build_dmz_true       = var.build_dmz ? 1 : 0
  build_bdl_true       = var.build_bdl ? 1 : 0
  azurerm_cidrs = {
    0 = cidrsubnet("10.1.2.0/24", 1, 0)
    1 = cidrsubnet(cidrsubnet("10.1.2.0/24", 1, 1), 1, 0)
    2 = cidrsubnet(cidrsubnet("10.1.2.0/24", 1, 1), 1, 1)
  }
}

network.tf

resource "azurerm_subnet" "subnet" {
  count                = local.build_ena_true + local.build_dmz_true + local.build_bdl_true
  name                 = "${var.azurerm_resource_prefix}-${local.env_short_name}-snet-${format("%03d", count.index + 1)}"
  resource_group_name  = var.azurerm_net_resource_group
  virtual_network_name = var.azurerm_network_name
  address_prefixes     = lookup(local.azurerm_cidrs, tostring(count.index), "")
}

Error using lookup

│ Error: Incorrect attribute value type
│
│   on network.tf line 21, in resource "azurerm_subnet" "subnet":
│   21:   address_prefixes     = lookup(local.azurerm_cidrs, tostring(count.index), "")
│     ├────────────────
│     │ count.index is 1
│     │ local.azurerm_cidrs is object with 3 attributes
│
│ Inappropriate value for attribute "address_prefixes": list of string required.

providers I am using

terraform {
  required_version = ">= 1.9.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.4.0"
    }
  }
}

Solution

  • address_prefixes in azurerm_subnet is the list of address prefixes to use for the subnet. tolist may not work here also, therefore [] can be used:

    resource "azurerm_subnet" "subnet" {
      count                = local.build_ena_true + local.build_dmz_true + local.build_bdl_true
      name                 = "${var.azurerm_resource_prefix}-${local.env_short_name}-snet-${format("%03d", count.index + 1)}"
      resource_group_name  = var.azurerm_net_resource_group
      virtual_network_name = var.azurerm_network_name
      address_prefixes     = [ local.azurerm_cidrs[count.index] ]
    }
    

    I have tested it and it works.