尚未在模块中声明数据资源“azurerm_virtual_network

kse8i1jr  于 2023-01-09  发布在  其他
关注(0)|答案(2)|浏览(151)

我有一个terraform,它可以在一个子网中创建一个虚拟网和一个虚拟机,为此,我需要从虚拟网中提取子网ID。
执行此操作时,我得到以下错误

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

这是我的文件结构:

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

外部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]
    }

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)
}

modules/spoke/vnet/outputs.tf

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

sz81bmfz1#

你的

resource "azurerm_virtual_network" "vnet"

是一个资源,不是数据源。因此,您必须将其作为资源引用(不要使用data.)。例如,将

virtual_network_name = data.azurerm_virtual_network.vnet.name

应该是

virtual_network_name = azurerm_virtual_network.vnet.name

或者您希望使用数据源,而不是资源。那么它应该

data "azurerm_virtual_network" "vnet"
bttbmeg0

bttbmeg02#

你的模块有很多问题,不幸的是,有这么多的方式来编写一个vnet模块,这就是为什么我会停下来写一个在这里。但是,我可以突出错误和分享文档。
第一资源azurerm_virtual_network至少具有以下问题:

  • 它已经缺少几个required属性[resource_group_name、address_space和其他属性]。请参阅azurerm_virtual_network以了解所有必需的属性以及使用此资源的示例。
    所需的最小属性为:
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
}
  • 它在从属资源azurerm_subnet中的引用也不正确。它不应被引用为data.azurerm_virtual_network.vnet.name,因为它不是数据源。正确的引用应为
virtual_network_name = azurerm_virtual_network.vnet.name
  • Terraform目前既提供独立的子网资源,并允许在虚拟网络资源中定义内联子网。此时,您不能将具有内联子网的虚拟网络与任何子网资源结合使用。这样做将导致子网配置冲突并覆盖子网。[复制自官方azurerm_virtual_network资源页]。这意味着您可以在azurerm_virtual_network资源内部创建子网,也可以使用azurerm_subnet资源创建子网。

更好的方法是使用显式的azurerm_subnet资源。Simplest Subnet资源如下所示,您可以随意使用countfor_each循环,只要听起来有趣且简单即可。建议使用for_each meta参数。

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
}

有关完整的azurerm_subnet资源属性参考和示例,请参阅azurerm_subnet
了解数据源:一个数据块请求Terraform从一个给定的数据源中读取数据,并以给定的本地名称导出结果。它们是只读对象,也可以读取Terraform作用域之外部署/管理的资源。

有关数据源的完整文档:https://developer.hashicorp.com/terraform/language/data-sources
count meta参数:https://developer.hashicorp.com/terraform/language/meta-arguments/count
for_each meta参数:https://developer.hashicorp.com/terraform/language/meta-arguments/for_each

而最常被遗忘的问题是:何时编写模块
希望能有所帮助。

相关问题