action-terraform-report
action-terraform-report copied to clipboard
Unhandled error: Error: invalid Terraform Plan JSON data
The terraform.json is a valid json but still getting an error as -
Unhandled error: Error: invalid Terraform Plan JSON data
How can we troubleshoot ?
it uses the following JSON schema: https://github.com/ahmadnassri/node-terraform-unidiff/blob/master/schema.json
please download your JSON, test it against that schema and let me know what you find.
also, include your Terraform version (wondering in they changed anything in a recent release)
Hi @ahmadnassri I am having this same error. I know for certain that in my case, the plan contains no items (i.e. no differences). Here is my data:
Stack trace:
Error: invalid Terraform Plan JSON data
at terraformUnidiff (file:///home/runner/work/_actions/ahmadnassri/action-terraform-report/v3/dist/index.js:104806:11)
at parse (file:///home/runner/work/_actions/ahmadnassri/action-terraform-report/v3/dist/index.js:104862:15)
at async file:///home/runner/work/_actions/ahmadnassri/action-terraform-report/v3/dist/index.js:104975:1
terraform.text
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
terraform.json
{
"format_version": "1.2",
"terraform_version": "1.6.3",
"planned_values": {
"root_module": {}
},
"configuration": {
"provider_config": {
"azurerm": {
"name": "azurerm",
"full_name": "registry.terraform.io/hashicorp/azurerm",
"version_constraint": "~\u003e 3.65",
"expressions": {
"features": [
{}
]
}
}
},
"root_module": {}
},
"timestamp": "2023-11-21T19:10:08Z",
"errored": false
}
Do I need to check the status code on the plan and add an if
conditional to your action in the case of an empty plan?
I am using v3
of your action.
Yeah this failed too with something as simple as
terraform {
# This module is now only being tested with Terraform 0.13.x. However, to make upgrading easier, we are setting
# 0.12.26 as the minimum version, as that version added support for required_providers with source URLs, making it
# forwards compatible with 0.13.x code.
required_version = ">= 0.12.26"
}
# website::tag::1:: The simplest possible Terraform module: it just outputs "Hello, World!"
output "hello_world" {
value = "Hello, World!"
}
to which the plan json looks like:
{
"format_version": "1.2",
"terraform_version": "1.6.0",
"planned_values": {
"outputs": {
"hello_world": {
"sensitive": false,
"type": "string",
"value": "Hello, World!"
}
},
"root_module": {}
},
"output_changes": {
"hello_world": {
"actions": [
"no-op"
],
"before": "Hello, World!",
"after": "Hello, World!",
"after_unknown": false,
"before_sensitive": false,
"after_sensitive": false
}
},
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.6.0",
"values": {
"outputs": {
"hello_world": {
"sensitive": false,
"value": "Hello, World!",
"type": "string"
}
},
"root_module": {}
}
},
"configuration": {
"root_module": {
"outputs": {
"hello_world": {
"expression": {
"constant_value": "Hello, World!"
}
}
}
}
},
"timestamp": "2023-12-19T16:29:59Z",
"errored": false
}
I get it's a toy example, but it should work right?
@danielloader If you are using v2 of the terraform setup try upgrading to hashicorp/setup-terraform@v3. It seems v2 with the wrapper includes standard error, standard out, etc appended to the json and text file even with just >. At least that helped in my case when I inspected the files.
Oh okay, I see the problem. It looks like in the version that I'm using, terraform 1.6.3, when the plan has no changes, the top level key resource_changes
is not present, but causes this plugin to throw an error because it's a required parameter in the schema.
So you can crash-proof this action by doing the following after generating a plan in your workflow named terraform.plan
:
terraform show -json terraform.plan | jq --argjson to_add '{"resource_changes":[]}' '. * $to_add' > terraform.json
This effectively ensures that the resource_changes
key is present, even if it is empty. This, however, is NOT a fix because when there are changes, they are being reported as zero...
bump?
So you can crash-proof this action by doing the following after generating a plan in your workflow named
terraform.plan
:terraform show -json terraform.plan | jq --argjson to_add '{"resource_changes":[]}' '. * $to_add' > terraform.json
This effectively ensures that the
resource_changes
key is present, even if it is empty. This, however, is NOT a fix because when there are changes, they are being reported as zero...
Thanks for that @mjcramer . I wrote this simple condition to check if resource_changes
is empty, then add the missing field + array else, do nothing.
terragrunt show -json tf.plan > tf-temp.json
# check if the .resource_changes is null in the tf.plan file and if it is,
# add an empty array to the json file else don't do anything.
if [ "$(jq '.resource_changes' tf-temp.json)" == "null" ]; then
echo "resource_changes is null"
jq --argjson to_add '{"resource_changes":[]}' '. * $to_add' tf-temp.json > tf.json
else
echo "resource_changes is not null"
cp tf-temp.json tf.json
fi
Then I use that tf.json
in the gh action to generate the report:
terraform-json: ${{ github.workspace }}/${{ matrix.directory }}/tf.json
Very nice! We should prolly find another github action, though, clearly this one has been abandoned...
@mjcramer just an idea, I started using this as well to update the PR description. Haven't gotten the markdown so it doesn't look the best but it's been nice having the terraform changes in the description. I just feed it the changes txt file. https://github.com/nefrob/pr-description