skip to Main Content

I have a terraform that creates a Vnet and a VM inside one of the subnets.
To do that, I need to extract the subnetIDs from the VNet.

When doing that, I get the following error

A data resource "azurerm_virtual_network" "vnet" has not been declared in module.weu_vnet.

This is my file structure:

|_ main.tf
|
|_ modules
|  |_ spoke
      |_ vnet
         |_ main.tf
         |_ outputs.tf
      |_ vm
         |_ main.tf

the outter main.tf:

    module "weu_vnet" {
      source  = "./modules/spoke/vnet"
      ...
    }
    
    module "weu_vm" {
      source  = "./modules/spoke/vm"
      ...
      subnet_id = module.weu_vnet.vnet_subnet_ids[1]
    }

The modules/spoke/vnet/main.tf

resource "azurerm_virtual_network" "vnet" {
  name                = local.vnet_name      
  subnet {
    name           = "vms"
  }
  ...
}

data "azurerm_subnet" "vnet_subnets" {
    name                 = data.azurerm_virtual_network.vnet.subnets[count.index]
    virtual_network_name = data.azurerm_virtual_network.vnet.name
    resource_group_name  = data.azurerm_virtual_network.vnet.resource_group_name
    count                = length(data.azurerm_virtual_network.vnet.subnets)
}

The modules/spoke/vnet/outputs.tf

output "vnet_subnet_ids" {
  value = data.azurerm_subnet.vnet_subnets.*.id
}

2

Answers


  1. Your

    resource "azurerm_virtual_network" "vnet"
    

    is a resource, not data source. So you have to refer to it as a resource (not use data.). For example, instead of

    virtual_network_name = data.azurerm_virtual_network.vnet.name
    

    it should be

    virtual_network_name = azurerm_virtual_network.vnet.name
    

    Or you want to use data source, not resource. Then it should be

    data "azurerm_virtual_network" "vnet"
    
    Login or Signup to reply.
  2. Your module has a lot of issues, unfortunately, there are so many ways of writing a vnet module which is why I will stop myself to write one here. However, I can highlight mistakes and share the documentation.

    The first resource azurerm_virtual_network has at least the following issues:

    • It is already missing a couple of required attributes [resource_group_name, address_space, and others]. refer to azurerm_virtual_network to know all required attributes and examples of using this resource.

    Minimum required attributes are:

    resource "azurerm_virtual_network" "vnet" {
      name                    = local.vnet_name ## OR ## var.vnet_name
      resource_group_name     = var.resource_group_name
      location                = var.location
      address_space           = var.address_space
    }
    
    • It is also referred to incorrectly in the dependent resource azurerm_subnet. It should not be referred to as data.azurerm_virtual_network.vnet.name as it is not a data source. The correct reference should be
    virtual_network_name = azurerm_virtual_network.vnet.name
    
    • Terraform currently provides both a standalone Subnet resource, and allows for Subnets to be defined in-line within the Virtual Network resource. At this time you cannot use a Virtual Network with in-line Subnets in conjunction with any Subnet resources. Doing so will cause a conflict of Subnet configurations and will overwrite subnets. [ Copied from the official azurerm_virtual_network resource page ]. Which means either you can create subnets inside the azurerm_virtual_network resource or with azurerm_subnet resource.

    The better way would be to use the explicit azurerm_subnet resource. The Simplest Subnet resource would be like follows , feel free to loop using count of for_each whichever sounds fun and easy to you. The recommendation would be the for_each meta argument.

    resource "azurerm_subnet" "example" {
    
      name                 = var.subnet_name
      resource_group_name  = var.resource_group_name
      virtual_network_name = azurerm_virtual_network.vnet.name
      address_prefixes     = var.subnet_address_prefixes
    }
    

    For complete azurerm_subnet resource attributes reference and examples please refer to azurerm_subnet.

    Understand Data sources:
    A data block requests that Terraform read from a given data source and export the result under the given local name. They are read-only objects and can also read resources deployed/managed out of terraform scope.

    Full documentation on data sources:
    https://developer.hashicorp.com/terraform/language/data-sources

    count Meta Argument:
    https://developer.hashicorp.com/terraform/language/meta-arguments/count

    for_each Meta Argument:
    https://developer.hashicorp.com/terraform/language/meta-arguments/for_each

    And the most often forgotten question:
    when-to-write-a-module

    Hoping that it helped.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search