You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform Azurerm:非可用区兼容区域用可用性集的配置错误排查

Terraform可用性集索引错误排查与解决

问题场景

通过自定义Terraform模块跨区域部署SD-WAN VM资源,设计逻辑为:

  • 区域支持可用区时,将VM部署到对应可用区
  • 区域不支持可用区时,创建可用性集并将VM加入该集
  • 仅当ha_enabled=true时部署secondary-vm

执行terraform plan时触发以下索引错误:

│ Error: Invalid index
│ 
│   on modules/transit-gateway/vm.tf line 51, in resource "azurerm_linux_virtual_machine" "primary-vm":
│   51:   availability_set_id             = local.primary_zone != "1" ? azurerm_availability_set.aset[count.index].id : null
│     ├────────────────
│     │ azurerm_availability_set.aset is empty tuple
│     │ count.index is 0
│ 
│ The given key does not identify an element in this collection value: the
│ collection has no elements.
╵
╷
│ Error: Invalid index
│ 
│   on modules/transit-gateway/vm.tf line 97, in resource "azurerm_linux_virtual_machine" "secondary-vm":
│   97:   availability_set_id             = local.secondary_zone != "2" ? azurerm_availability_set.aset[count.index].id : null
│     ├────────────────
│     │ azurerm_availability_set.aset is empty tuple
│     │ count.index is 0
│ 
│ The given key does not identify an element in this collection value: the
│ collection has no elements.
╵

错误原因

  1. 可用性集创建逻辑完全写反:
    当前可用性集的count配置为local.primary_zone != "1" ? 0 : 1,意思是区域支持可用区时创建可用性集,与设计逻辑(不支持可用区时才创建)完全相反。
  2. VM引用可用性集的条件错误:
    VM中用local.primary_zone != "1"判断是否引用可用性集,实际应该是当区域不支持可用区(local.primary_zone为null)时才引用。
  3. 索引引用逻辑错误:
    当可用性集count=0时,它是空元组,但VM仍尝试用count.index(值为0)索引它,导致触发无效索引错误。

解决方案

1. 修正可用性集的创建逻辑

将可用性集的count改为:仅当区域不支持可用区(local.primary_zone为null)时才创建:

resource "azurerm_availability_set" "aset" {
  count = local.primary_zone == null ? 1 : 0

  name                = "silverpeak-sdwan${local.country_code}-aset"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

2. 修正VM的可用性集引用逻辑

主VM(primary-vm)修改

将availability_set_id的判断改为:仅当区域不支持可用区时,引用可用性集ID,否则设为null:

availability_set_id = local.primary_zone == null ? azurerm_availability_set.aset[0].id : null

或者用try函数做更安全的容错处理(避免可用性集不存在时的索引错误):

availability_set_id = try(azurerm_availability_set.aset[0].id, null)

备VM(secondary-vm)修改

同理修改availability_set_id:

availability_set_id = local.secondary_zone == null ? azurerm_availability_set.aset[0].id : null

或容错版本:

availability_set_id = try(azurerm_availability_set.aset[0].id, null)

3. 逻辑验证

  • 部署到支持可用区的区域(如southeastasia):可用性集count=0,VM的availability_set_id为null,自动使用配置的可用区
  • 部署到不支持可用区的区域(如northcentralus):可用性集count=1,VM会正确加入该可用性集,无索引错误

内容的提问来源于stack exchange,提问作者Hannes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:30:57