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. ╵
错误原因
- 可用性集创建逻辑完全写反:
当前可用性集的count配置为local.primary_zone != "1" ? 0 : 1,意思是区域支持可用区时创建可用性集,与设计逻辑(不支持可用区时才创建)完全相反。 - VM引用可用性集的条件错误:
VM中用local.primary_zone != "1"判断是否引用可用性集,实际应该是当区域不支持可用区(local.primary_zone为null)时才引用。 - 索引引用逻辑错误:
当可用性集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
相关产品推荐
相关产品推荐

