Terraform问题:虚拟机规模集模块无法引用子网模块
解决方案
一、先解决核心报错:VNet模块的输出引用错误
你当前的错误是因为VNet模块里的dynamic "subnet"是嵌套在azurerm_virtual_network资源内的配置块,不是独立的azurerm_subnet资源,因此无法通过azurerm_virtual_network.subnet.name引用。同时你还存在重复创建子网的问题(VNet模块和独立Subnet模块都在创建子网),这会导致后续资源冲突,必须二选一。
1. 修改VNet模块的main.tf
删除嵌套的dynamic "subnet"块,只保留VNet本身的配置:
resource "azurerm_virtual_network" "vnet" { name = var.name location = var.location resource_group_name = var.resource_group_name address_space = var.vnet_address_space } output "vnet_name" { value = azurerm_virtual_network.vnet.name } output "vnet_id" { value = azurerm_virtual_network.vnet.id }
2. 修正VNet模块的output.tf
移除错误的子网输出:
output "name" { value = azurerm_virtual_network.vnet.name } output "id" { value = azurerm_virtual_network.vnet.id }
二、优化Subnet模块的输出,方便VMSS引用子网ID
VMSS的subnet_id需要传入子网的资源ID,不是名字。修改Subnet模块的output.tf,生成按子网key和名字映射的ID:
output "subnet_ids_by_key" { description = "通过子网配置的key获取对应ID" value = { for key, subnet in azurerm_subnet.subnet : key => subnet.id } } output "subnet_ids_by_name" { description = "通过子网名称获取对应ID" value = { for key, subnet in azurerm_subnet.subnet : subnet.name => subnet.id } }
三、修正根模块中VMSS的子网引用
在根main.tf里,通过Subnet模块的输出传递子网ID给VMSS。比如你要使用uks_vms这个key对应的子网(名称为sm_uks_vms):
module "vmss_linux" { source = "./modules/vmss-linux" name = format("vmss-%s-lin-uks", var.vmss_lin_uks_name) resource_group_name = var.vmss_lin_uks_rgs location = var.vmss_lin_uks_location network_interface_name = var.vmss_lin_uks_network_interface_name network_interface_primary = true ipconfig_name = var.vmss_lin_uks_ipconfig_name ipconfig_primary = true # 通过子网配置的key获取ID(推荐,key唯一不会重复) ipconfig_subnet = module.azure_subnets.subnet_ids_by_key["uks_vms"] # 或者通过子网名称获取ID # ipconfig_subnet = module.azure_subnets.subnet_ids_by_name["sm_uks_vms"] depends_on = [module.azure_subnets] }
四、增强VMSS模块的健壮性
给VMSS模块的variables.tf添加类型约束,避免参数错误:
variable "name" { type = string description = "VM规模集名称" } variable "resource_group_name" { type = string description = "资源组名称" } variable "location" { type = string description = "VMSS部署的Azure区域" } variable "sku" { type = string default = "Standard_B1s" description = "VM实例的SKU" } variable "instances" { type = number default = 3 description = "规模集实例数量" } variable "network_interface_name" { type = string description = "网络接口名称" } variable "network_interface_primary" { type = bool description = "是否为主要网络接口" } variable "ipconfig_name" { type = string description = "IP配置名称" } variable "ipconfig_primary" { type = bool description = "是否为主要IP配置" } variable "ipconfig_subnet" { type = string description = "绑定的子网资源ID" }
额外提醒
- 不要同时在VNet模块和独立Subnet模块创建子网,会导致资源重复创建报错。
- VMSS里硬编码
admin_password存在安全风险,建议用random_password资源生成随机密码,或配置Azure AD登录。
内容的提问来源于stack exchange,提问作者theangrytech
相关产品推荐
相关产品推荐

