Terraform 迭代嵌套数据

问题描述 投票:0回答:1

我正在尝试基于提供相关配置的 yaml 配置文件创建 New Relic 的服务级对象。 我的 yaml 配置:

slo:
  targets:
  - first_slo:
    name: "My First SLO"
    endpoints:
      - path: /api/method1
        method: GET
      - path: /api/method2
        method: PUT
    objectives:
      availability:
        threshold: 99.9
  - first_slo:
    name: "My Second SLO"
    endpoints:
      - path: /api/method12
        method: GET
      - path: /api/method23
        method: PUT
    objectives:
      availability:
        threshold: 99.99

我想迭代这个示例配置来构建对象,但我正在努力使用嵌套迭代来形成正确的 NRQL 查询。

我的地形文件:

resource "newrelic_service_level" "availability" {
  for_each  = var.config.slo.targets
  guid = var.guid
  name = "${each.value.name} - Availability"
  description = "Proportion of requests that are served successfully."

  events {
    account_id = var.account_id
    valid_events {
      from = "Transaction"
      where = "transactionType='Web' AND entityGuid = '${var.guid}' AND (OR_CONDITION_BETWEEN_ALL_THE_METHODS_AND_URIS)"
    }
    bad_events {
      from = "Transaction"
      where = "transactionType= 'Web' AND entityGuid = '${var.guid}' AND numeric(response.status) >= 500 AND (OR_CONDITION_BETWEEN_ALL_THE_METHODS_AND_URIS)"
    }
  }

  objective {
    target = each.value.objectives.availability.threshold
    time_window {
      rolling {
        count = 7
        unit = "DAY"
      }
    }
  }
}

所以基本上我在这里尝试做的是使用 NRQL 查询创建一个服务级别,该查询仅针对与此特定目标相关的 URI 和方法的特定组合进行过滤 - 我在配置中拥有的 URI 和方法文件。

所以对于第一个 SLO,

OR_CONDITION_BETWEEN_ALL_THE_METHODS_AND_URIS
应该翻译成这样:
(request.uri = '/api/method1' AND request.method = 'GET') OR (request.uri = '/api/method2' AND request.method = 'PUT')

我目前的解决方案是手动构建查询并将其添加到每个 SLO 的配置中,但它不可读且难以维护。

我将非常感谢有关如何动态构建查询的任何建议。

terraform newrelic terraform0.12+
1个回答
0
投票

您当然可以使用 Terraform 构建该查询。这是一个小

.tf
文件,展示了您如何做到这一点:

locals {
  config = yamldecode(file("${path.root}/vars.yaml"))
  parsed = [for d in local.config.slo.targets : {
    name : d["name"]
    condition : join(" OR ", [for e in d["endpoints"] : "(request.uri = '${e["path"]}' AND request.method = '${e["method"]}')"])
  }]
}

output "parsed" {
  value = local.parsed
}

这期望您的 yaml 文件位于其旁边,名称为

vars.yaml
,并生成:

$ terraform plan

Changes to Outputs:
  + parsed = [
      + {
          + condition = "(request.uri = '/api/method1' AND request.method = 'GET') OR (request.uri = '/api/method2' AND request.method = 'PUT')"
          + name      = "My First SLO"
        },
      + {
          + condition = "(request.uri = '/api/method12' AND request.method = 'GET') OR (request.uri = '/api/method23' AND request.method = 'PUT')"
          + name      = "My Second SLO"
        },
    ]

对于您的模块,您可以只使用

join(...)
部分代替
OR_CONDITION_BETWEEN_ALL_THE_METHODS_AND_URIS
。重复它应该没问题(只要你记录它,自然),但如果你不喜欢大长线,你可以创建一个子模块来封装它。或者您可以在预处理
locals
块中构建查询字符串,可能使用
merge
函数将查询字符串添加到每个目标配置的其余部分。

© www.soinside.com 2019 - 2024. All rights reserved.