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 asdata.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 withazurerm_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.