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 ?
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.
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.
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.
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).
data "external" "json" {
program = ["echo", "${var.json}"]
}
output "map" {
value = "${data.external.json.result}"
}
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
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"]
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With