How to inject terraform variables in a json file

Hey team, I’m having trouble finding in the documentation on how to inject a variable into a json file. After the plan, in the monitoring platform the name of the dashboard is ${var.aws_account_name} EC2 Dashboard, and the actual variable value did not get injected. How would i fix this?

{
  "dashboard_title": "${var.aws_account_name} EC2 Dashboard"
}


in main.tf file

variable "aws_account_name" {
  type        = string
  description = "the aws account name"
}

Hi @aravind-bigfish,

The typical answer is to produce the JSON using Terraform’s jsonencode function, which knows how to map all of Terraform’s own data types to corresponding JSON ones.

jsonencode({
  dashboard_title = "${var.aws_account_name} EC2 Dashboard"
})

You didn’t show the part of your configuration which uses this result, so I can’t show an example in context. If you’re not sure how to use the above, please share the part of your configuration which will use the JSON result and I can show where the above function call in would fit into it.

for example, this is the resource being spun up

im using jsondecode to be able to parse certain keys

  config = jsondecode(file("./test/config/cloud_run.json"))
locals {
  dashboard_title       = lookup(local.config,"dashboard_title")
  dashboard_description = lookup(local.config,"description")
}

resource "newrelic_one_dashboard" "cloudrun_dashboard" {

  name = local.dashboard_title
  page {
    name        = local.dashboard_title
    description = local.dashboard_description

Hmm, interesting… if you’re going to be immediately reading that dashboard_title value out of the result anyway, wouldn’t it be less circuitous to put the logic for populating it directly in that local value?

locals {
  dashboard_title = "${var.aws_account_name} EC2 Dashboard"
}

I’m not asking this question to just be difficult; just trying to get my head around what the use-case is, because encoding a data structure to JSON and then immediately decoding it again feels strange! :thinking:

Of course !, I need to iterate through and perform some lookups. Ideally what i had in mind was have a json file for my dashboard stuff, and in the resource creation will be using lookup and find certain keys in the json.

the problem is when i use decode, it treats the ${var.aws_account_name} as a verbatim string and in the resource creation, it literally uses that string name and not the interpolated name. Would i be using the template function in this scenario.

If you want to generate the JSON itself via a template then I would suggest following the strategy described in Generating JSON or YAML from a template, where the external file is a Terraform template file which consists entirely of a call to jsonencode, whose argument describes the JSON data structure to build.

You can then pass certain values into the template execution scope (using the second argument to templatefile) in order to use dynamic values in the result.

The external template might therefore look something like this:

${jsonencode({
  dashboard_title = "${aws_account_name} EC2 Dashboard"
})}

If you place that template in a file cloud_run.json.tmpl then you could call it like this:

locals {
  config = jsondecode(templatefile("${path.module}/cloud_run.json.tmpl", {
    aws_account_name = var.aws_account_name
  }))
}

The template will therefore generate JSON dynamically based on the variables passed into the template, and then jsondecode will immediately decode it again to get a data structure.

Producing JSON just to immediately decode it again is unusual, as I mentioned previously, but technically possible. A different way to do this without the extra serialization/deserialization through JSON would be to define the same data structure inline as a local value, without using templates or JSON at all:

locals {
  config = {
    # Place in here the same content that would've been
    # in the jsonencode call inside the template above.
    dashboard_title = "${var.aws_account_name} EC2 Dashboard"
  }
}

With both approaches, local.config will be the resulting data structure, and so the title will be in local.config.dashboard_title.

1 Like

I followed this approach you mentioned, and got it to work. Thanks allot Mart!