通过 Terraform 传递文件夹中的所有文件

Gé *_* Fa 2 monitoring grafana terraform

我正在为我们的内部项目构建一个监控堆栈。我希望他们能够设计自己的监控仪表板以在 Grafana 内部使用,所以我无法预测这些仪表板的名称。

我创建了一个名为 的文件夹grafana_dashboard,我将在其中指示他们将仪表板存储为 JSON 文件,并且我希望将该文件夹的所有内容传递到 Grafana 实例。

我尝试过很多变体:

resource "grafana_dashboard" "dashboards" {
  for_each = fileset(path.module, "grafana_dashboard/*.json")
  config_json = "${each.key}"
  depends_on = [aiven_service.grafana]
}
Run Code Online (Sandbox Code Playgroud)

但不断收到此错误:

Error: invalid character 'g' looking for beginning of value

  on ../modules/monitoring/grafana.tf line 139, in resource "grafana_dashboard" "dashboards":
 139: resource "grafana_dashboard" "dashboards" {
Run Code Online (Sandbox Code Playgroud)

你们谁能看出我做错了什么吗?

这是我尝试传递的 .json 文件之一的示例:

{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      },
      {
        "datasource": "Prometheus",
        "enable": true,
        "expr": "sum(changes(nginx_ingress_controller_config_last_reload_successful_timestamp_seconds{instance!=\"unknown\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[30s])) by (controller_class)",
        "hide": false,
        "iconColor": "rgba(255, 96, 96, 1)",
        "limit": 100,
        "name": "Config Reloads",
        "showIn": 0,
        "step": "30s",
        "tagKeys": "controller_class",
        "tags": [],
        "titleFormat": "Config Reloaded",
        "type": "tags"
      }
    ]
  },
  "description": "Ingress-nginx supports a rich collection of prometheus metrics. If you have prometheus and grafana installed on your cluster then prometheus will already be scraping this data due to the scrape annotation on the deployment.",
  "editable": false,
  "gnetId": 9614,
  "graphTooltip": 0,
  "id": 18,
  "iteration": 1574177838584,
  "links": [],
  "panels": [
    {
      "columns": [
        {
          "text": "Current",
          "value": "current"
        }
      ],
      "datasource": "Prometheus",
      "fontSize": "100%",
      "gridPos": {
        "h": 15,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "height": "1024",
      "id": 85,
      "links": [],
      "options": {},
      "pageSize": 15,
      "scroll": true,
      "showHeader": true,
      "sort": {
        "col": 1,
        "desc": false
      },
      "styles": [
        {
          "alias": "Time",
          "dateFormat": "YYYY-MM-DD HH:mm:ss",
          "pattern": "Time",
          "type": "date"
        },
        {
          "alias": "TTL",
          "colorMode": "cell",
          "colors": [
            "rgba(245, 54, 54, 0.9)",
            "rgba(237, 129, 40, 0.89)",
            "rgba(50, 172, 45, 0.97)"
          ],
          "dateFormat": "YYYY-MM-DD HH:mm:ss",
          "decimals": 0,
          "pattern": "Current",
          "thresholds": [
            "0",
            "691200"
          ],
          "type": "number",
          "unit": "s"
        },
        {
          "alias": "",
          "colorMode": null,
          "colors": [
            "rgba(245, 54, 54, 0.9)",
            "rgba(237, 129, 40, 0.89)",
            "rgba(50, 172, 45, 0.97)"
          ],
          "decimals": 2,
          "pattern": "/.*/",
          "thresholds": [],
          "type": "number",
          "unit": "short"
        }
      ],
      "targets": [
        {
          "expr": "avg(nginx_ingress_controller_ssl_expire_time_seconds{kubernetes_pod_name=~\"$controller\",namespace=~\"$namespace\",ingress=~\"$ingress\"}) by (host) - time()",
          "format": "time_series",
          "instant": false,
          "intervalFactor": 1,
          "legendFormat": "{{ host }}",
          "metric": "gke_letsencrypt_cert_expiration",
          "refId": "A",
          "step": 1
        }
      ],
      "title": "Ingress Certificate Expiry",
      "transform": "timeseries_aggregations",
      "type": "table"
    }
  ],
  "refresh": "5s",
  "schemaVersion": 19,
  "style": "dark",
  "tags": [
    "nginx"
  ],
  "templating": {
    "list": [
      {
        "allValue": ".*",
        "current": {
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "",
        "hide": 0,
        "includeAll": true,
        "label": "Namespace",
        "multi": false,
        "name": "namespace",
        "options": [],
        "query": "label_values(nginx_ingress_controller_config_hash, controller_namespace)",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": ".*",
        "current": {
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "",
        "hide": 0,
        "includeAll": true,
        "label": "Controller Class",
        "multi": false,
        "name": "controller_class",
        "options": [],
        "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\"}, controller_class) ",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": ".*",
        "current": {
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "",
        "hide": 0,
        "includeAll": true,
        "label": "Controller",
        "multi": false,
        "name": "controller",
        "options": [],
        "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\",controller_class=~\"$controller_class\"}, controller_pod) ",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      },
      {
        "allValue": ".*",
        "current": {
          "text": "All",
          "value": "$__all"
        },
        "datasource": "Prometheus",
        "definition": "",
        "hide": 0,
        "includeAll": true,
        "label": "Ingress",
        "multi": false,
        "name": "ingress",
        "options": [],
        "query": "label_values(nginx_ingress_controller_requests{namespace=~\"$namespace\",controller_class=~\"$controller_class\",controller=~\"$controller\"}, ingress) ",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 2,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "query",
        "useTags": false
      }
    ]
  },
  "time": {
    "from": "now-5m",
    "to": "now"
  },
  "timepicker": {
    "refresh_intervals": [
      "5s",
      "10s",
      "30s",
      "2m",
      "5m",
      "15m",
      "30m",
      "1h",
      "2h",
      "1d"
    ],
    "time_options": [
      "5m",
      "15m",
      "1h",
      "6h",
      "12h",
      "24h",
      "2d",
      "7d",
      "30d"
    ]
  },
  "timezone": "browser",
  "title": "Cert-manager",
  "uid": "nginx",
  "version": 12
}
Run Code Online (Sandbox Code Playgroud)

这是可行的,所以我知道我可以做到这一点,但不适合我的需求,因为我需要对每个文件的名称进行硬编码:

resource "grafana_dashboard" "nginx_ingress_controller" {
  config_json = templatefile("${path.module}/grafana_dashboard/nginx-ingress-controller.json", { DS_PROMETHEUS = local.prometheus_datasource_name })
  depends_on = [aiven_service.grafana]
}
Run Code Online (Sandbox Code Playgroud)

yda*_*coR 6

config_json您需要实际使用参数中的文件内容grafana_dashboard

将资源定义切换为以下内容就足够了:

resource "grafana_dashboard" "dashboards" {
  for_each    = fileset(path.module, "grafana_dashboard/*.json")
  config_json = file("${path.module}/${each.key}")
  depends_on  = [aiven_service.grafana]
}
Run Code Online (Sandbox Code Playgroud)