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

Terraform count.index索引local值报无效索引错误排查

问题根因

报错核心是集合类型转换逻辑错误,和变量定义为list(string)还是list(object)没有直接关系:

  • 你写的for x in var.xxx_list : x.name => x表达式,会把原本支持数字索引按顺序取值的列表(list),转换成仅支持字符串键取值的映射(map,即报错中提到的object类型集合)
  • 转换完成后的local.alarm_names、local.metric_names实际结构如下,所有键都是配置的name字符串,不存在0、1、2、3这类数字键,自然无法用count.index的数字值做索引查询:
# 转换后的local.metric_names实际结构
{
  CPUUtilization = { name = "CPUUtilization" }
  DiskReadOps    = { name = "DiskReadOps" }
  NetworkIn      = { name = "NetworkIn" }
  NetworkOut     = { name = "NetworkOut" }
}
正确配置方案

以下两种方案均可直接落地,根据使用场景选择即可:

方案1:直接引用原始列表配合count(改动最小)

既然已经确认两个列表长度始终一致、同位置元素一一对应,完全不需要额外转map,直接引用原始变量列表按索引取值即可,变量也可以简化为list(string)类型减少冗余。
修改后的main.tf代码:

resource "aws_cloudwatch_metric_alarm" "ec2_cpu" {
  count                     = length(var.alarm_names_list)
  alarm_name                = "${var.alarm_names_list[count.index]}-${var.name_instance_outout}"
  comparison_operator       = "GreaterThanOrEqualToThreshold"
  evaluation_periods        = "2"
  metric_name               = var.metric_names_list[count.index]
  namespace                 = "AWS/EC2"
  period                    = "120"
  statistic                 = "Average"
  threshold                 = "80"
  alarm_description         = "This metric monitors ec2 cpu utilization"
  insufficient_data_actions = []
  dimensions = {
    InstanceId = var.ec2_id_output
  }
}

对应简化后的variables.tf代码:

variable "metric_names_list" {
  type    = list(string)
  default = ["CPUUtilization", "DiskReadOps", "NetworkIn", "NetworkOut"]
}

variable "alarm_names_list" {
  type    = list(string)
  default = ["cpu-utilization-duk-test", "memory-utilization", "network-inbound", "network-outbound"]
}

方案2:合并结构后用for_each(生产环境更稳妥)

如果担心后续调整列表顺序导致告警意外重建,可以先把两个列表按索引合并成统一的映射结构,用for_each创建资源,这种方式不受列表顺序变动影响。
修改后的main.tf代码:

locals {
  # 按索引合并两个列表,生成以告警名为键的固定映射
  alarm_metric_map = {
    for idx, alarm_name in var.alarm_names_list : alarm_name => {
      alarm_name  = alarm_name
      metric_name = var.metric_names_list[idx]
    }
  }
}

resource "aws_cloudwatch_metric_alarm" "ec2_cpu" {
  for_each                  = local.alarm_metric_map
  alarm_name                = "${each.value.alarm_name}-${var.name_instance_outout}"
  comparison_operator       = "GreaterThanOrEqualToThreshold"
  evaluation_periods        = "2"
  metric_name               = each.value.metric_name
  namespace                 = "AWS/EC2"
  period                    = "120"
  statistic                 = "Average"
  threshold                 = "80"
  alarm_description         = "This metric monitors ec2 cpu utilization"
  insufficient_data_actions = []
  dimensions = {
    InstanceId = var.ec2_id_output
  }
}

变量定义和方案1保持一致即可。

注意:for_each方案下后续调整告警配置时,只会修改对应键匹配的资源,不会因为列表顺序变化批量重建告警,生产环境优先推荐该写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:54:41