0

I'm trying to create a list of maps from my list of subnet names so I've created the following:

  1. created a variable named subnet_names of type list of strings
  2. created a null resource block to create a list of maps from this list, like this:
resource "null_resource" "subnet_mapping" {
   count = "${length(var.subnet_names)}"

   triggers = {
    name   = "${element(var.subnet_names, count.index)}"
    number = "${count.index}"
  }
}

if I only execute this block I have my list of maps correctly but when I try to use this list of maps with a dynamic block this is not working.

resource "azurerm_virtual_network" "virtual_network" {
  address_space = "${var.cidr_network_range}"
  location = "${var.location}"
  name = "${var.virtual_network_resource_name}"
  resource_group_name = "${var.resource_group_name}"
  count = "${length(var.subnet_names)}"

  dynamic "subnet"{
    for_each = [for s in null_resource.subnet_mapping: {
      name = s.name
      prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)
    }]

    content {
      name = subnet.value.name
      address_prefix = subnet.value.prefix
    }
  }

  depends_on = [null_resource.subnet_mapping]
}

resource "null_resource" "subnet_mapping" {
  count = "${length(var.subnet_names)}"

  triggers = {
    name   = "${element(var.subnet_names, count.index)}"
    number = "${count.index}"
  }
}


resource "azurerm_resource_group" "virtual_network_group" {
  location = "${var.location}"
  name = "${var.resource_group_name}"
}

it should be valid, but I still don't have the output of the null_resource so it fails

dynamic "subnet"{
    for_each = [for s in null_resource.subnet_mapping: {
      name = s.name
      prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)
    }]

    content {
      name = subnet.value.name
      address_prefix = subnet.value.prefix
    }
  }

  depends_on = [null_resource.subnet_mapping]
}

my error message:

Error: Unsupported attribute

  on main.tf line 10, in resource "azurerm_virtual_network" "virtual_network":
  10:       name = s.name

This object does not have an attribute named "name".


Error: Unsupported attribute

  on main.tf line 10, in resource "azurerm_virtual_network" "virtual_network":
  10:       name = s.name

This object does not have an attribute named "name".


Error: Unsupported attribute

  on main.tf line 10, in resource "azurerm_virtual_network" "virtual_network":
  10:       name = s.name

This object does not have an attribute named "name".


Error: Unsupported attribute

  on main.tf line 10, in resource "azurerm_virtual_network" "virtual_network":
  10:       name = s.name

This object does not have an attribute named "name".


Error: Unsupported attribute

  on main.tf line 11, in resource "azurerm_virtual_network" "virtual_network":
  11:       prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)

This object does not have an attribute named "number".


Error: Unsupported attribute

  on main.tf line 11, in resource "azurerm_virtual_network" "virtual_network":
  11:       prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)

This object does not have an attribute named "number".


Error: Unsupported attribute

  on main.tf line 11, in resource "azurerm_virtual_network" "virtual_network":
  11:       prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)

This object does not have an attribute named "number".


Error: Unsupported attribute

  on main.tf line 11, in resource "azurerm_virtual_network" "virtual_network":
  11:       prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,s.number)

This object does not have an attribute named "number".

4c74356b41
  • 69,186
  • 6
  • 100
  • 141
MrByte
  • 97
  • 1
  • 10

2 Answers2

0

From the message, I'm not clear how many Vnets do you want to create, because your code is a little confusing. For your issue with the null_resource, I don't think it's a good choice, I recommend the locals.

Here I assume you only want to create one Vnet with serial subnets and use a list to store the names of the subnets, then the example core code below:

locals {
  subnets = [for sname in var.subnet_names: {
    name = sname
    # the index begin from 0, so you need to add 1
    number = index(var.subnet_names, sname) + 1
  }]
}

resource "azurerm_virtual_network" "virtual_network" {
  address_space = "${var.cidr_network_range}"
  location = "${var.location}"
  name = "${var.virtual_network_resource_name}"
  resource_group_name = "${var.resource_group_name}"


  dynamic "subnet"{
    for_each = [for s in local.subnets: {
      name = s.name
      prefix = cidrsubnet(var.cidr_network_range, 8 , s.number)
    }]

    content {
      name = subnet.value.name
      address_prefix = subnet.value.prefix
    }
  }
}
Charles Xu
  • 29,862
  • 2
  • 22
  • 39
0

I solved this way, I've created a variable named

variable "subnets" {
  type = list(map(string))
  description = "A list of maps of names and network addresses bits for subnets that will be created inside this network (this is parallel to subnet_prefixes array)."
}
resource "azurerm_virtual_network" "virtual_network" {
  address_space = var.cidr_network_range
  location = var.location
  name = var.virtual_network_resource_name
  resource_group_name = var.resource_group_name

  dynamic "subnet"{
    for_each = [for subnet in var.subnets: {
      name = subnet.name
      prefix = cidrsubnet(element(var.cidr_network_range, 0),8 ,subnet.number)
    }]
    content {
      name = subnet.value.name
      address_prefix = subnet.value.prefix
    }
  }
}

resource "azurerm_resource_group" "virtual_network_group" {
  location = var.location
  name = var.resource_group_name
}

This way I already created the map, I would like to have created it automatically as I posted before but it seems to not be very common in terraform way.

In Charles Xu example the mapping will be created based on a sequence (1,2,3) and I would like to use it always in different ways like (21, 24, 26) So the only solution I could find was to force the map before.

Anyway, thank you everyone

MrByte
  • 97
  • 1
  • 10