terraform-provider-external: "external" provider returns an invalid json
This issue was originally opened by @Phydeauxman as hashicorp/terraform#17632. It was migrated here as a result of the provider split. The original body of the issue is below.
Terraform Version
Terraform v0.11.3
+ provider.azurerm v1.2.0
+ provider.external v1.0.0
Terraform Configuration Files
variable ilbase_resourceId {
default = "/subscriptions/<my_subscription>/resourceGroups/my-rg/providers/Microsoft.Web/hostingEnvironments/my-ilbase/capacities/virtualip"
}
data "external" "aseVip" {
program = ["az", "resource", "show", "--ids", "${var.ilbase_resourceId}"]
}
Debug Output
Crash Output
Expected Behavior
The JSON object would be returned to terraform
Actual Behavior
Terraform config generates error:
data.external.aseVip: data.external.aseVip: command "az" produced invalid JSON: json: cannot unmarshal object into Go value of type string
Steps to Reproduce
Additional Context
If after I provision the App Service Environment I run the command below:
az resource show --ids "/subscriptions/<my_subscription>/resourceGroups/my-rg/providers/Microsoft.Web/hostingEnvironments/my-ilbase/capacities/virtualip"
It returns the JSON object below:
{
"additionalProperties": {
"internalIpAddress": "10.10.1.11",
"outboundIpAddresses": [
"52.224.70.119"
],
"serviceIpAddress": "52.224.70.119",
"vipMappings": []
},
"id": null,
"identity": null,
"kind": null,
"location": null,
"managedBy": null,
"name": null,
"plan": null,
"properties": null,
"sku": null,
"tags": null,
"type": null
}
References
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 11
- Comments: 18 (2 by maintainers)
Hi @Phydeauxman! Sorry this didn’t work as expected.
At the moment this data source is limited to dealing only with simple string values, because the provider model requires each attribute to have a type and this one is typed as “map of strings”. The
additionalPropertiesproperty in your example is hitting this error because it’s not convertible to a string.It’s currently necessary to flatten the result to use only a single level of keys and only string values. For the lists in your example, it’d be required to use some sort of delimiter and then use the
splitfunction to divide the single string into a list.We do intend to make this more flexible in future but need to do some other work in Terraform Core first so that it’s possible within provider schema to describe the result type of this attribute. (Or more accurately, to describe that its type is not known until it is read.) Since it seems we don’t already have an issue open to represent this, I’m going to label this one to represent that feature. We need to get through some other work first so there won’t be any immediate action here, but we will return to this once that underlying work is done and share more details.
This provider was originally written before Terraform had a
jsondecodefunction. I agree that with that function now present it would be better to have a new data source that can just run a program and capture its output as a string.I would suggest doing that as a new data source in the
localprovider though, not as an extension of theexternaldata source, because theexternaldata source was designed for use with programs tailored to work with Terraform (as a middle-ground to allow writing small glue programs rather than entire new Terraform providers), not for executing arbitrary existing software with no modifications.As an example, the new data source might look like this:
As with
external, it would be important to use this only for programs that don’t have externally-visible side-effects, because the program would be run during the planning phase rather than the apply phase. But unlikeexternalit would impose no constraints on the output except that it be UTF-8 encoded (because Terraform language strings are Unicode, not raw bytes) and leave the user to decide how and whether to parse it.I don’t work directly on either the
externalor thelocalproviders, so I’m suggesting the above just as a design starting point, and I can’t promise it would be accepted exactly like that. If you’re interested in working on such a thing I’d suggest starting by opening an issue in thelocalprovider repository to describe what you’re intending to do and get feedback from the team that maintains that provider before doing work on it, in case there are design constraints for that provider that I’m not considering.Raw output and raw input sound much more useful than json to me. Relatively few legacy command line programs handle JSON. For those that do, the terraform json encoding and decoding functions are present. For csv, yaml, base64, newline delimited text, and all of the other formats in common use, adding a json wrapper is unwelcome overhead.