Home > Enterprise >  A data resource "azurerm_virtual_network" has not been declared in module
A data resource "azurerm_virtual_network" has not been declared in module

Time:01-06

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
}

CodePudding user response:

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"

CodePudding user response:

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.

  • Related