20

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 ?

artxur
1,9601 gold badge20 silver badges28 bronze badges
asked Sep 22, 2017 at 18:50

4 Answers 4

22
variable "json" {
 default = "{\"foo\": \"bar\"}"
}
data "external" "json" {
 program = ["echo", "${var.json}"]
}
output "map" {
 value = "${data.external.json.result}"
}
Alexander Pogrebnyak
45.8k10 gold badges111 silver badges123 bronze badges
answered Dec 13, 2017 at 21:18
Sign up to request clarification or add additional context in comments.

3 Comments

how, where is var.json defined in this example? is it read from an external file?
It is just a variable with the JSON string.
Added explicit variable declaration
7

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
answered Aug 26, 2019 at 11:46

1 Comment

The Jsondecode function does not necessarily return a map. In fact, I personally haven't ever seen it return a map. From my experience, it always returns an object. I'm sure this is heavily dependent on the structure of your JSON string.
7

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"]
 }
 }
}
answered Jul 10, 2020 at 10:52

Comments

5

It seems to be that the way to do the is by using the external data, as it return a map from a json response.

Stephen Ostermiller
25.8k18 gold badges96 silver badges117 bronze badges
answered Sep 22, 2017 at 20:19

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.