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

Terraform遍历嵌套Map时如何保留原键名而非固定键名?

问题:Terraform嵌套遍历保留Map原键名的问题

现有变量定义

variable "db_alarm_metrics" {
  type = map(any)
  description = "Database metrics to create alarms for"
  default = {
    "ReadIOPS" = {
      "threshold" = "20",
      "period" = "60000"
    },
    "WriteIOPS" = {
      "threshold" = "20",
      "period" = "60000"
    }
  }
}
variable "aggregation_db_primary_db_instance_id" {
  type        = string
  description = ""
  default = "mysql-aggregation"
}

当前使用的locals代码

locals {
  instance_metrics = flatten([
    for instance_type in [ var.aggregation_db_primary_db_instance_id, "${var.aggregation_db_primary_db_instance_id}-replica" ] : [
      for metric in var.db_alarm_metrics : {
        instance_type = instance_type
        metric = metric
      }
    ]
  ])
}

当前输出结果

执行terraform console查看local.instance_metrics得到:

{
    "instance_type" = "mysql-aggregation"
    "metric" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation"
    "metric" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation-replica"
    "metric" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation-replica"
    "metric" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },

期望输出结果

希望保留var.db_alarm_metrics中的原键名作为对象键:

{
    "instance_type" = "mysql-aggregation"
    "ReadIOPS" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation"
    "WriteIOPS" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation-replica"
    "ReadIOPS" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },
  {
    "instance_type" = "mysql-aggregation-replica"
    "WriteIOPS" = {
      "period" = "60000"
      "threshold" = "20"
    }
  },

问题原因及修正方案

你当前的内层循环只遍历了var.db_alarm_metrics的值,没有捕获对应的键名,所以只能用固定字符串"metric"作为键。要保留原键名,需要同时遍历Map的键和值,并使用Terraform的动态键语法来构建对象。

修正后的locals代码如下:

locals {
  instance_metrics = flatten([
    for instance_type in [var.aggregation_db_primary_db_instance_id, "${var.aggregation_db_primary_db_instance_id}-replica"] : [
      for metric_name, metric_attrs in var.db_alarm_metrics : {
        instance_type = instance_type
        "${metric_name}" = metric_attrs
      }
    ]
  ])
}

关键修改点:

  1. 内层循环从for metric in var.db_alarm_metrics改为for metric_name, metric_attrs in var.db_alarm_metrics,这样metric_name会拿到原Map的键(如ReadIOPS),metric_attrs拿到对应的值。
  2. 对象构建时用"${metric_name}" = metric_attrs替代原来的metric = metric,通过动态键语法将原键名作为对象的键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:12:51