Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decoding JSON string to terraform map

Tags:

terraform

I'm using the HTTP data source to retrieve data from an internal service. The service returns JSON data.

I can't interpolate the returned JSON data and look up data in it.

For example:

module A

data "http" "json_data" {
    url = "http://myservice/jsondata"

    # Optional request headers
    request_headers {
       "Accept" = "application/json"
    }
}

output "json_data_key" {
    value = "${lookup(data.http.json_data.body, "mykey")}"
}

main.tf

provider "aws" {
   region = "${var.region}"
   version = "~> 0.1"
}

module "moduleA" {
   source = "../../../terraform-modules/moduleA"
}

resource "aws_instance" "example" {
    ami = "ami-2757f631"
    instance_type = "${module.moduleA.json_data_key}"
}

The lookup function will fail to extract the key within the JSON data.

Is there any way to decode the JSON data into a terraform map ?

like image 447
Ofer Velich Avatar asked Sep 22 '17 18:09

Ofer Velich


People also ask

Can Terraform read JSON files?

Terraform also supports an alternative syntax that is JSON-compatible. This syntax is useful when generating portions of a configuration programmatically, since existing JSON libraries can be used to prepare the generated configuration files.

How do you call a JSON in Terraform?

If this JSON file is something you intend to include as part of your Terraform configuration (e.g. checked in to version control alongside the . tf files) then you can load the data structure from it into Terraform using the file function and the jsondecode function.

What is JSONEncode in Terraform?

jsonencode encodes a given value to a string using JSON syntax. The JSON encoding is defined in RFC 7159. This function maps Terraform language values to JSON values in the following way: Terraform type. JSON type.

What is JSONEncode Roblox?

Description: The JSONEncode function transforms a Lua table into a JSON object or array based on the following guidelines: Keys of the table must be either strings or numbers. If a table contains both, an array takes priority (string keys are ignored).


3 Answers

data "external" "json" {
  program = ["echo", "${var.json}"]
}

output "map" {
  value = "${data.external.json.result}"
}
like image 152
victor m Avatar answered Oct 13 '22 19:10

victor m


Since 0.12 version of the Terraform you can use jsondecode function to decode json into a Terraform map. More details on: https://www.terraform.io/docs/configuration/functions/jsondecode.html

example from the page above:

> jsondecode("{\"hello\": \"world\"}")
{
  "hello" = "world"
}
> jsondecode("true")
true
like image 6
mlysiu Avatar answered Oct 13 '22 19:10

mlysiu


Not directly related to map convertion, but here's an additional sample with jsondecode if you got a multi-value secret (=JSON) in AWS SecretsManager & you want to use separate values from it in another service as I've struggled with this.

Retrieving the secret:

data "aws_secretsmanager_secret" "oauth_client" {
  name = "oauth-client"
}

data "aws_secretsmanager_secret_version" "oauth_client" {
  secret_id = data.aws_secretsmanager_secret.oauth_client.id
}

Using it at Lambda, as an example:

resource "aws_lambda_function" "lambda" {
  [...]
  environment {
    variables = {
      OAUTH_CLIENT_ID     = jsondecode(data.aws_secretsmanager_secret_version.oauth_client.secret_string)["client_id"]
      OAUTH_CLIENT_SECRET = jsondecode(data.aws_secretsmanager_secret_version.oauth_client.secret_string)["client_secret"]
    }
  }
}
like image 6
tpschmidt Avatar answered Oct 13 '22 18:10

tpschmidt