How to provide value to a placeholder in JSON

Hi, I am trying to create Grafana alert for almost 20 services using grafana terraform provider. Added alerts in a plugable way to services… Each service has different set of alerts like “500 errors”, “5xx error percentage” etc. So, relative time range and alert types and service owners etc are service specific data. Then alert consitions, data source, summary message etc would be alert specific data. Finally in main.tf file, I have added the required attribute for resource “grafana_rule_group”. In which I have dynamic block for rules in each service. And inside each rule, created dynamic bloack for conditions(data–A,B or C) in each rule. So, the model attribute is different for data block A, B or C. So, used a template.tpl for conditions and provided the alert specifc input variables to the placeholders in the template using templatefile()(in alert_config.tf file). In the condition, there is a attribute called ‘expr’. Which is like ““expr”: “sum by(status) (increase(http_server_requests_seconds_count{service={{service}}, status=~” 500 “}[1m]))”,”. I can replace the {{$service}} with actual service name, only in main.tf. Not sure how to do that in terraform. Tried many ways. But got error as: " Error: Invalid function argument

201

202│ on …/gfalerts/shasl_alerts/main.tf line 53, in resource “grafana_rule_group” “shasl_rule_group”:

203│ 53: model = data.key == “A” ? templatefile(“${jsonencode(data.value.model)}”, { service = each.key }) : jsonencode(data.value.model)

204│ ├────────────────

205│ │ data.value.model is “{\n "datasource": {\n "type": "prometheus",\n "uid": "000000018"\n },\n "editorMode": "code",\n "exemplar": true,\n "expr": "sum by(status) (increase(http_server_requests_seconds_count{service={{service}}, status=~"500"}[1m]))",\n "instant": true,\n "interval": "1m",\n "intervalFactor": 1,\n "intervalMs": 1000,\n "legendFormat": "500 errors",\n "maxDataPoints": 43200,\n "range": false,\n "refId": "A"\n}\n”

206

207│ Invalid value for “path” parameter: open "{\n "datasource": {\n

208│ "type": "prometheus",\n "uid": "000000018"\n },\n

209│ "editorMode": "code",\n "exemplar": true,\n "expr": "sum

210│ by(status)

211│ (increase(http_server_requests_seconds_count{service={{service}},

212│ status=~"500"}[1m]))",\n "instant": true,\n "interval": "1m",\n

213│ "intervalFactor": 1,\n "intervalMs": 1000,\n "legendFormat": "500

214│ errors",\n "maxDataPoints": 43200,\n "range": false,\n "refId":

215│ "A"\n}\n": file name too long."

The thing is, I have dynamically generated a json with a variable in it. And, want to replace the variable in the json with the dynamic value again(without creating an external tenmplate file). So, Is there a way in terraform to spply values to variable in a json(but not expecting to read the json from a file)

Hi @francisabletreasa,

I’m afraid I don’t have enough familiarity with Grafana to fully understand your end-goal, but I can at least point out an intermediate problem:

The first argument to the templatefile function is supposed to be the path to a file on disc containing the template to render. You’re passing the result of jsonencode, which is producing something that is not a valid filename. The error you’ve shared is a result of trying to use that JSON string as if it were a filename, which failed on your system because your operating system (Windows?) enforces a maximum length for a file path. However, even if that length limit were not there, it seems unlikely that you have a file on your computer whose name is that long JSON string.

I’m guessing that you tried to follow the example in Generating JSON or YAML from a template, which shows a template interpolation of the result from jsonencode. That interpolation was supposed to appear in the separate file containing the template.

However, I don’t think that following that example would get you quite what you wanted here, since you seem to want to treat data.value.model itself as a template, which is not directly possible because it’s an object rather than a string. Instead, I think it would be better to transform the data structure before you pass it to jsonencode, but I’m not sure exactly what to propose for that since you’ve not shared any configuration source code for me to start from.

1 Like

ok yea… Somehow fixed the issue… Thanks for your effort