Multiple subnets in same VNet with Terrafrom

Viewed 228

I'm completely new to terraform and I'm trying to learn and write a TF code to automate Azure VM deployment. I'm trying to cover each parts as modules (except rg) rather than keeping it in a single main.tf file. My intention is to create 1 vnet (TESTVNET) and create multiple subnets in same Vnet, where I can define the subnet name and address in my tfvars file.

I'm able to reach till creation on VNet, but cant loop through the defined subnets

Please go through my code. File Main.tf

    resource "azurerm_resource_group" "resource_group" {
      name     = var.RGname
      location = var.RGlocation
    }
    
    module "VNET" {
      source              = "./Modules/NetworkConfig"
      name                = var.VNETname
      address_space       = var.address_space
      location            = var.RGlocation
      resource_group_name = azurerm_resource_group.resource_group.name
    }
    
    module "SUBNETS" {
      source               = "./Modules/SubnetConfig"
      Subnetlist = var.Subnetlist
      virtual_network_name = module.VNET.vnet_name
      resource_group_name  = azurerm_resource_group.resource_group.name
      depends_on           = [azurerm_resource_group.resource_group, module.VNET.vnet]
    
    }

Variables.tf (of main)

    variable "RGlocation" {
    }
    
    variable "RGname" {
    }
    
    variable "VNETname" {
    }
    
    variable "address_space" {
    }
    
    variable "Subnetlist" {
      type = map(object({
        name    = list(string)
        address = list(string)
    }))
    }

File main.tfvars

    RGlocation = "westus"
    RGname     = "TEST-RG1"
    
    VNETname      = "TEST-VNET-01"
    address_space = "10.0.0.0/16"
    
    
    Subnetlist = {
      "list" = {
        name    = ["TESTSUBNET","TESTSUBNET1","TESTSUBNET2"]
        address = ["10.0.1.0/24","10.0.2.0/24","10.0.3.0/24"]
      }
    }

File Subnets.tf (module)

    resource "azurerm_subnet" "SUBNETS" {
        for_each=var.Subnetlist
        name=each.value.name
        address_prefixes=each.value.address
          resource_group_name  = var.resource_group_name
          virtual_network_name = var.virtual_network_name
        
        }

File variable.tf (subnet module)

    variable "resource_group_name" {
    }
    
    variable "virtual_network_name" {
    }
    
    variable "Subnetlist" {
      type = map(object({
        name    = list(string)
        address = list(string)
      }))
    }

Below if the error that I'm getting

    ╷
    │ Error: Incorrect attribute value type
    │
    │   on Modules\SubnetConfig\Subnet.tf line 3, in resource "azurerm_subnet" "SUBNETS":
    │    3: name=each.value.name
    │     ├────────────────
    │     │ each.value.name is list of string with 3 elements
    │
    │ Inappropriate value for attribute "name": string required.

Could anyone please tell me how to resolve it? Also, please do let me know if this is not the right approach.

1 Answers

The way you iterate over Subnetlist is incorrect - you only get the value of "list" key, ending up with a bundle of subnets instead of individual items. Make it a map of individual subnet objects instead:

variable "Subnetlist" {
  type = map(object({
    name    = string
    address = string
  }))
}

Then pass it in tfvars like:

Subnetlist = {
    "s1" = { name = "TESTSUBNET", address = "10.0.1.0/24" },
    "s2" = { name = "TESTSUBNET1", address = "10.0.2.0/24" },
    "s3" = { name = "TESTSUBNET2", address = "10.0.3.0/24" }
}

Finally consume it in the module like this:

resource "azurerm_subnet" "SUBNETS" {
    for_each = var.Subnetlist
    name = each.value.name
    address_prefixes = each.value.address
    resource_group_name = var.resource_group_name
    virtual_network_name = var.virtual_network_name
}
Related