hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.53k stars 9.52k forks source link

jsondecode function #10363

Closed matti closed 5 years ago

matti commented 7 years ago

jsonencode could be used as a way to pass lists and maps to module if there was a jsondecode function (or jsonparse etc).

ckyoog commented 6 years ago

And better support nested map and list.

apparentlymart commented 6 years ago

Hi @matti and @ckyoog! This is an old issue, but I have some news about it!

The current configuration language can't support a function like this because it has no way to model a function whose return type depends on its input value.

For a little while now we've been working on a revamp of the configuration language to address a number of shortcomings and limitations, and this is one of the things the new implementation can now support.

We're going to be rolling this new implementation out cautiously because it's a big change that will almost definitely contain some small breaking changes that we need to manage. However, we are planning to release an opt-in preview version of it soon to gather feedback and find as many bugs as possible. This initial release should include the new jsondecode function, though it will still be subject to some limitations initially since it will take a few steps to update all of Terraform's internals to support the new system.

ckyoog commented 6 years ago

Thank you @apparentlymart! It's really a good news! I can't wait to see what brilliant features the new implementation can bring to us.

matti commented 6 years ago

just found out that @ewbankkit has done this: https://github.com/EvilSuperstars/terraform-provider-jsondecode

matti commented 6 years ago

"The subset of JSON that can be decoded is limited - boolean, number, string, object with string values and array of strings." - see tests: https://github.com/EvilSuperstars/terraform-provider-jsondecode/blob/master/decode/data_source_decode_test.go

matti commented 6 years ago

I also gave a try, not as good, but might help someone https://github.com/matti/terraform-json-map

robinbowes commented 6 years ago

Is jsondecode due to be released in 0.12 ?

ewbankkit commented 6 years ago

I'm hoping that Reliable JSON syntax promised here will give us what we need.

robinbowes commented 6 years ago

That's not the same as being able to process json.

apparentlymart commented 6 years ago

Although it's not included in the list in the article there, jsondecode is planned to be in the 0.12 release, along with improvements to jsonencode allowing it to work with arbitrarily-nested types rather than just with lists and maps of strings.

@robinbowes is correct that this is something separate than "Reliable JSON syntax", which is about Terraform's handling of its own configuration files written in JSON format (.tf.json files, in other words).

robinbowes commented 6 years ago

@apparentlymart Do you have any idea when 0.12 will be released? Is it days/weeks/months away?

apparentlymart commented 6 years ago

There are more details on the 0.12 release in the announcement blog post.

robinbowes commented 6 years ago

"later this summer" - some time before mid-Sept? :)

One thing that occurred to me - will providers also be updated for 0.12?

For example, I'd like to use the http provider to pull JSON from an api, but unless it's been re-written for 0.12 then it won't support the more complex JSON structures.

chrisminton commented 6 years ago

The http provider JSON use-case is one I am interested in too

apparentlymart commented 6 years ago

The http provider just returns the raw body string from the response, so it shouldn't need any changes itself to support reading JSON values. Instead, you'd pass its result through jsondecode(...) to get the data structure out.

apparentlymart commented 5 years ago

I just tried the following in v0.12.0-alpha1:

output "foo" {
  value = jsondecode(<<EOT
{
  "foo": "bar",
  "baz": ["boop"]
}
EOT
  )
}
$ terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

foo = {
  "baz" = [
    "boop",
  ]
  "foo" = "bar"
}

The jsondecode function is available for experimental use in the v0.12.0-alpha1 release and will be included in the eventual v0.12.0 final release.

Thanks for filing this feature request, and for the patience while we got through the groundwork to make a function like this possible.

udondan commented 5 years ago

Already commented on https://github.com/terraform-providers/terraform-provider-aws/issues/4789 but also related here:

Here's a partial solution for Terraform v0.11 without any dependencies:

variable json_input {
  default = <<EOT
{
  "foo": "bar",
  "baz": "boop"
}
EOT
}

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

data.external.helper.result is the full map stored in secret_string and elements can be accessed as data.external.helper.result["example"]

Or throw it into a module and return the whole map as output:

output "parsed" {
  value = "${data.external.helper.result}"
}
$ terraform apply
data.external.helper: Refreshing state...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

parsed = {
  baz = boop
  foo = bar
}

The only limitation is, that the external data provider can apparently not deal with arrays. So only works with json maps...

json: cannot unmarshal array into Go value of type string

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.