Elasticstack provider error with triple quotes in transform json

I am having issues with the elasticstack_elasticsearch_watcher resource parsing triple quotes in json. I’ve copied the json of a watcher from Kibana and separated the json into actions, condition, input, metadata, trigger and transform json files as this matches the arguments for this resource (I don’t see a way to load the entire json in the docs, but that is beside the point). Everything works fine except for transform which has a triple quoted section (“”") and I get the following error:

│ Error: "transform" contains an invalid JSON: invalid character '"' after object key:value pair
│
│   with elasticstack_elasticsearch_watch.watchers["my_watcher"],
│   on watchers.tf line 59, in resource "elasticstack_elasticsearch_watch" "watchers":
│   59:     transform = file("watchers/${each.value}_transform.json")
│

Here is my terraform config:

locals {
  watchers = toset([
    "my_watcher"
  ])
}

resource "elasticstack_elasticsearch_watch" "watchers" {
  for_each = local.watchers
    watch_id = "${each.value}"
    active = true

    actions = file("watchers/${each.value}_actions.json")
    condition = file("watchers/${each.value}_condition.json")
    input = file("watchers/${each.value}_input.json")
    transform = file("watchers/${each.value}_transform.json")
    trigger = file("watchers/${each.value}_trigger.json")
}

Here is the json I am trying:

{
        "transform": {
          "script": {
            "source": """
                return [
                  '@type': 'MessageCard',
                  '@context': 'https://schema.org/extensions',
                  'themeColor': 'a30200',
                  'summary': 'Watcher alert: ' + ctx.metadata.name,
                  'title': 'my_watcher',
                  'sections': [
                  [
                    'facts': [
                      [
                        'name': 'Errors Found:',
                        'value': ctx.payload.hits.total.toString()
                      ]
                    ]
                  ]
                ],
                'potentialAction': [
                  [
                    '@type': 'OpenUri',
                    'name': 'View Errors',
                    'targets': [
                      [
                        'os': 'default',
                        'uri': ctx.metadata.dashboard_url
                      ]
                    ]
                  ]
                ]
                ]""",
            "lang": "painless"
          }
        }
}

If I hand craft the transform argument the way the terraform resource wants it, I get it to work, but for efficiency sake, I’d rather not have to do that, but here is what works in the terraform resource:

    transform = jsonencode({
      "script" = <<EOF
        return [
          "@type" = "MessageCard",
          "@context" = "https://schema.org/extensions",
          "themeColor" = "a30200",
          "summary" = "Watcher alert: " + "ctx.metadata.name",
          "title" = "my_watcher",
          "sections" = [
            [
              "facts" = [
                [
                  "name" = "Errors Found:",
                  "value" = "ctx.payload.hits.total.toString()"
                ]
              ]
            ]
          ],
          "potentialAction" = [
            [
              "@type" = "OpenUri",
              "name" = "View Errors",
              "targets" = [
                [
                  "os" = "default",
                  "uri" = "ctx.metadata.dashboard_url"
                ]
              ]
            ]
          ]
        ]
      EOF
    })

but I’d rather just do this:

transform = file("watchers/${each.value}_transform.json")

Thanks in advance for any advice you can provide and please feel free to ask for clarification!

Hi @Alfaxomo,

JSON doesn’t support this “triple quote” syntax, so this error is correct.

Either you will need to write a valid JSON file (which would involve escaping all of the quotes and newlines in your big string) or you will need to write a Terraform expression that generates the JSON you need.

If your objection to the inline jsonencode call was that it is too verbose to include inline, then you could try using the templatefile function instead, which would mean that everything between your <<EOF and its matching EOF would be placed in the separate template file, instead of inline in your module source code.

1 Like

Thank you for this @apparentlymart, much appreciated. Perhaps I’ll follow up with Elasticsearch as this json was exported directly from Kibana. I was considering using a templatefile as well, but wanted to clear up why the json was causing a problem. Thanks again!