Terraform:遍历复杂对象列表

Posted

技术标签:

【中文标题】Terraform:遍历复杂对象列表【英文标题】:Terraform: loop through a list of complex objects 【发布时间】:2022-01-04 19:08:48 【问题描述】:

我想遍历一个包含两个警报对象的列表,配置如下 - 问题是如何通过循环每个警报指标列表来动态生成 metric_query 块..

   locals
    prefix = terraform.workspace

    alarm_WithExpression = [
         "name" : "XXX",
          "expression" : "m1/m2",
          "metrics" : [
             "id" : "m1", "name" : "YYYY", "statistic" : "Sum", "period" : 21600 ,
             "id" : "m2", "name" : "ZZZZZ" ,"statistic" : "Sum", "period" : 21600 
          ],
          "threshold" : 0.2,
          "comparison_operator" : "LessThanThreshold",
          "period" : 21600,
          "data_points" : 2,
          "treat_missing_data" : "notBreaching"
        ,
         "name" : "AAAA",
          "expression" : "m1/(m2-m3)",
          "metrics" : [
             "id" : "m1", "name" : "BBBB", "statistic" : "Sum", "period" : 21600 ,
             "id" : "m2", "name" : "CCCC", "statistic" : "Sum", "period" : 21600 ,
             "id" : "m3", "name" : "DDDD", "statistic" : "Sum", "period" : 21600 
          ],
          "threshold" : "0.2",
          "comparison_operator" : "LessThanThreshold",
          "period" : 21600,
          "data_points" : 2,
          "treat_missing_data" : "notBreaching"
        
      ]
    

这是指标警报声明:

resource "aws_cloudwatch_metric_alarm" "metrics-withExpression_alarm" 
  for_each            = local.prefix == "production" ?  : for index,m in local.alarm_WithExpression : index => m
  alarm_name          = "$local.prefix-$each.value.name"
  comparison_operator = each.value.comparison_operator
  evaluation_periods  = each.value.period
  threshold           = each.value.threshold
  treat_missing_data  = each.value.treat_missing_data
  datapoints_to_alarm = each.value.data_points

  metric_query 
    id          = "e"
    expression  = each.value.expression
    return_data = "true"
  

  # loop inside list of metrics ??
  dynamic "metric_query" 
    for_each = for index,k in local.alarm_WithExpression.metrics : index => k
    content 
      id = each.value.id

      metric 
        metric_name = each.value.name
        namespace   = "$local.prefix-metrics"
        period      = each.value.period
        stat        = each.value.statistic
      
    
  

我收到此计划错误:

╷
│ Error: Unsupported attribute
│ 
│   on cloudwatch-alarms.tf line 177, in resource "aws_cloudwatch_metric_alarm" "metrics-withExpression_alarm":
│  177:     for_each = for index,k in local.alarm_WithExpression.metrics : index => k
│     ├────────────────
│     │ local.alarm_WithExpression is tuple with 2 elements
│ 
│ This value does not have any attributes.
╵
ERROR: 1

如何遍历每个警报指标列表?

【问题讨论】:

【参考方案1】:

你的问题在于这部分:

local.alarm_WithExpression.metrics

给你一些背景。 local.alarm_WithExpression 是一个列表。该列表没有metrics 属性,因此.metrics 没有给您想要的。

我相信您的目标可以使用他们所谓的splat expressions 来实现,即

local.alarm_WithExpression[*].metrics

用简单的英语可以理解为:

对于local.alarm_withExpression 中的每个对象,获取其metrics 属性

【讨论】:

我得到了这个错误,因为它只能看到第一个 for_each 语句:each.value 是具有 8 个属性的对象 │ │ 这个对象没有名为“id”的属性。【参考方案2】:

你可以像下面这样实现这个

  dynamic "metric_query" 
    for_each = each.value.metrics
    content 
      id = metrics.value["id"]

      metric 
        metric_name = metrics.value["name"]
        namespace   = "$local.prefix-metrics"
        period      = metrics.value["period"]
        stat        = metrics.value["statistic"]
      
    
  

【讨论】:

我试了一下,得到以下错误:│错误:引用未声明的资源││在 cloudwatch-alarms.tf 第 179 行,资源“aws_cloudwatch_metric_alarm”“metrics-withExpression_alarm”:│179:id = metrics.value["id"] │ │ 一个托管资源 "metrics" "value" 没有在根模块中声明。 ╵

以上是关于Terraform:遍历复杂对象列表的主要内容,如果未能解决你的问题,请参考以下文章

Terraform 在“计数”中设置多个变量

如何在 terraform 中运行 kubectl apply 命令

Terraform:对象列表值没有属性

如何使用 terraform 将 aws ec2 私有 ips 传递给模板文件

在同一个 TF 脚本中使用多个 Terraform 提供程序(GCP 和 Kubernetes)创建资源

Terraform:从对象列表中检索值