如何通过Terraform在Azure创建内部负载均衡器时使用现有VM
如何在Terraform中为内部负载均衡器关联已有Azure VM
要把已有Azure VM加入内部负载均衡器(ILB)的后端池,核心是通过Terraform的数据资源获取VM/网卡信息,再创建网卡与后端池的关联资源——这才是适配内部LB场景的正确方式,NAT规则是用于公网LB端口转发的,确实不适用这里。
步骤1:获取已有VM及网卡的数据
用Terraform的data块直接拉取目标VM的信息,重点拿到VM绑定的网络接口ID,因为LB后端池是和网卡关联的:
# 获取单台已有VM的数据(替换成你的VM名称和资源组) data "azurerm_virtual_machine" "existing_vm_01" { name = "vm-dev-01" resource_group_name = "rg-vm" } # 如果要批量获取同资源组下带特定标签的VM,用复数数据资源 data "azurerm_virtual_machines" "existing_vms" { resource_group_name = "rg-vm" tags = { environment = "dev" } }
步骤2:修正原代码中的错误
你的原代码有两处问题,必须先修正:
azurerm_lb_rule里的probe_id引用错误,应该指向azurerm_lb_probe.h-probe.id,不是不存在的terra-ipp.idbackend_address_pool_ids需要传入数组格式(哪怕只有一个后端池),原代码直接传字符串会报错
步骤3:创建网卡与后端池的关联
用azurerm_network_interface_backend_address_pool_association资源,把已有VM的网卡绑定到LB后端池:
# 单台VM关联 resource "azurerm_network_interface_backend_address_pool_association" "vm_01_assoc" { network_interface_id = data.azurerm_virtual_machine.existing_vm_01.network_interface_ids[0] backend_address_pool_id = azurerm_lb_backend_address_pool.terra-app.id } # 批量关联多个VM(基于上面的复数数据资源) resource "azurerm_network_interface_backend_address_pool_association" "vm_assocs" { for_each = { for vm in data.azurerm_virtual_machines.existing_vms.vms : vm.name => vm } network_interface_id = vm.network_interface_ids[0] backend_address_pool_id = azurerm_lb_backend_address_pool.terra-app.id }
完整修正后的代码示例
整合所有部分,包含数据资源、LB配置和关联逻辑:
data "azurerm_virtual_network" "vnet0001" { name = "vnet0001" resource_group_name = "vnet-rg" } data "azurerm_subnet" "sub" { name = "vnet00001-sub" resource_group_name = "vnet-rg" virtual_network_name = data.azurerm_virtual_network.vnet0001.name } # 获取已有VM数据 data "azurerm_virtual_machine" "existing_vm_01" { name = "vm-dev-01" resource_group_name = "rg-vm" } data "azurerm_virtual_machine" "existing_vm_02" { name = "vm-dev-02" resource_group_name = "rg-vm" } # 确保资源组存在(如果你的LB资源组已经存在,可以换成data块获取) resource "azurerm_resource_group" "terra-app" { name = "rg-lb-dev" location = "East US2" } resource "azurerm_lb" "terra-app" { name = "lb-dev" location = "East US2" resource_group_name = azurerm_resource_group.terra-app.name sku = "Standard" sku-tier = "Regional" frontend_ip_configuration { name = "frontendip" zones = ["1", "2", "3"] subnet_id = data.azurerm_subnet.sub.id private_ip_address_allocation = "Dynamic" } } resource "azurerm_lb_backend_address_pool" "terra-app" { loadbalancer_id = azurerm_lb.terra-app.id name = "lb-backendpool" } resource "azurerm_lb_probe" "h-probe" { loadbalancer_id = azurerm_lb.terra-app.id name = "hp1" port = 111 protocol = "Tcp" # TCP探针不需要request_path,可移除 } resource "azurerm_lb_rule" "lb-rule" { loadbalancer_id = azurerm_lb.terra-app.id name = "lb-r1" protocol = "Tcp" frontend_port = 111 backend_port = 111 frontend_ip_configuration_name = "frontendip" backend_address_pool_ids = [azurerm_lb_backend_address_pool.terra-app.id] probe_id = azurerm_lb_probe.h-probe.id } # 关联已有VM到LB后端池 resource "azurerm_network_interface_backend_address_pool_association" "vm_01_assoc" { network_interface_id = data.azurerm_virtual_machine.existing_vm_01.network_interface_ids[0] backend_address_pool_id = azurerm_lb_backend_address_pool.terra-app.id } resource "azurerm_network_interface_backend_address_pool_association" "vm_02_assoc" { network_interface_id = data.azurerm_virtual_machine.existing_vm_02.network_interface_ids[0] backend_address_pool_id = azurerm_lb_backend_address_pool.terra-app.id }
关键注意事项
- 内部LB的后端池必须通过网卡关联,不能直接关联VM,这是Azure的架构要求。
- 如果你的VM有多个网卡,要指定正确的网卡ID(上面的示例用的是第一个网卡)。
- 确保已有VM和LB在同一个虚拟网络(或对等互联的网络)中,否则无法关联。
内容的提问来源于stack exchange,提问作者Sagar Hiremath
相关产品推荐
相关产品推荐

