cli icon indicating copy to clipboard operation
cli copied to clipboard

ERROR: state.out.json is not a valid terraform plan json output.

Open kjr247 opened this issue 5 years ago • 12 comments

Description : OS: macos catalina docker terraform-compliance v1.2.7 I'm just running the scripts on the docs, and it doesn't seem to work when I pass it proper json files. Is this still maintained?

To Reproduce

  1. <Either a sample terraform code, or your terraform plan file if it doesn't have any confidential information>
# main.tf
provider "aws" {
  region = var.region
}

locals {
  common_tags = {
    Environment        = var.env_name
    TerraformWorkspace = var.env_name
  }
}

terraform {
  backend "remote" {
    organization = "*******"
    workspaces {
      prefix = "******"
    }
  }
}
# variables.tf
variable "region" {
  description = "AWS region"
}

variable "env_name" {
}
  1. <Used terraform-compliance parameters> ??
  2. using docker
$ terraform show -json > state.out.json
$ terraform state pull > state.out
$ terraform-compliance -p state.out.json
# terraform-compliance v1.2.7 initiated

# ERROR: state.out.json is not a valid terraform plan json output.
  1. <Your feature/scenario/steps>
Given I have followed the instructions from the docs to run the above commands
Then it must not error
And it must show me all the power and glory of terraform-compliance.

Expected behavior : Shouldn't error out and should work based on the docs.

Tested versions :

  • terraform-compliance v1.2.7
  • Terraform v0.12.26
  • Python 2.7.16

Additional context

kjr247 avatar Jun 24 '20 17:06 kjr247

Hello @kjr247,

Yes the tool is maintained, since we have a release frequency around once a week.

I tried to reproduce your problem, but couldn't. It works with states without a problem, maybe using an remote backend make things weird on the terraform side. Is it possible to share the state.out.json ?

Apart from that, in case you didn't terraform apply, I suppose you need to change your tests like ;

Given I want to see all the power and glory of terraform-compliance
When I run terraform-compliance
Then it first requires a valid state file
And terraform apply must run in order to create that

eerkunt avatar Jun 25 '20 09:06 eerkunt

I'm seeing the same issue with a state file of mine, created with 0.12.26 (state version 4). Unfortunately, adding the --debug command line flag generates zero additional output:

terraform-compliance v1.3.0 initiated

ERROR: tfstate.out is not a valid terraform plan json output.

Running terraform-compliance via Python's trace module (python -mtrace --trace venv/lib/python3.8/site-packages/terraform_compliance/main.py --features scenarios/ --planfile tfstate.out --debug) shows that the error is being thrown by terraform_compliance.common.readable_plan.ReadablePlan:69, which is asserting that a number of keys exist in the JSON file specified as --planfile.

In my case, for a state file, it's failing on the first one: format_version. Which is completely correct, because a Terraform State version 4 file doesn't have a format_version key, it has a version key. It also doesn't have a values key, which is checked a few lines down. However, the JSON that's output by terraform show -json has the format_version and values keys, and works with terraform-compliance. It appears that ReadablePlan is actually looking for the JSON terraform show output, not a state file.

This is unfortunate, since it means that even the simple example in the documentation of terraform state pull > state.out && terraform-compliance -p state.out [...] fails.

Digging a bit deeper into the code, it appears that for my JSON state file, the call to filetype.guess is returning None, which is skipping over calling convert_terraform_plan_to_json() which would fix this. This is likely because terraform state files are already JSON files, not binary like the plan files.

The best thing that I can figure is that the example in the docs of terraform state pull > state.out && terraform-compliance -p state.out [...] is wrong, and really assumes that there's a terraform show -json in between there. Unfortunately, that's quite problematic as it means that you need an initialized terraform directory, complete with providers, in order to check a state file... which eliminates the possibility of doing something like pointing terraform-compliance at an entire directory of state files (e.g. from an S3 bucket, or some other remote state storage).

jantman avatar Aug 10 '20 16:08 jantman

First off, let me say that I absolutely love this project. It has the distinct possibility of being able to do absolutely wonderful things for our current workflow, which is based on detecting issues after-the-fact.

I believe this is the same as #235. I'd be willing to try to work up a PR to fix this, but it feels to me like there are a few other issues that I'd run into... mainly that I really want to be able to call terraform-compliance programmatically via Python instead of just via the cli entrypoint, as well as use multiple feature directories, but it appears that the current layout of terraform_compliance.main.cli precludes that.

jantman avatar Aug 10 '20 17:08 jantman

I am also seeing this issue with terraform 12.26.

I think the problem is here: https://github.com/eerkunt/terraform-compliance/blob/02be1d2c4c98754f41998ccb2e9557708eac141b/terraform_compliance/common/readable_plan.py#L56

Specifically the state file that I have doesn't have a 'format_version' field in the json. I am also not seeing 'values' in data. which is another check right below that might fail.

Guessing that state file formatting changed in newer versions of terraform.

markvoll avatar Aug 21 '20 18:08 markvoll

Getting this issue with:

  • Terraform v0.12.28
  • terraform-compliance v1.3.4 initiated

pat-wong-ronin avatar Sep 17 '20 18:09 pat-wong-ronin

This is interesting, I can't reproduce the problem with 0.12.28.

Is it possible to provide a plan.out.json ? Maybe I am missing something

eerkunt avatar Nov 05 '20 10:11 eerkunt

I am also seeing this issue with:

  • Terraform v0.13.5
  • terraform-compliance v1.3.6

when running :

# A
$ terraform state pull > state.out
$ terraform-compliance --debug -p ./state.out-f ./scenarios

OR

# B 
$ terraform show -json > state.out.json
$ terraform-compliance --debug -p ./state.out -f ./scenarios

I get

terraform-compliance v1.3.6 initiated

ERROR: ./state.out is not a valid JSON file

However, when I do this:

# C
$ terraform plan -out=state.out
$ terraform-compliance --debug -p ./state.out -f ./scenarios

It works.

I have several other states that use # B and work. I'm only seeing this on one of my code bases. Is there an explanation for this?

dkinder avatar Nov 06 '20 20:11 dkinder

Also having this issue:

// my state file

bash-5.0# cat state.out | jq .
{
  "version": 4,
  "terraform_version": "0.12.29",
  "serial": 582,
  "lineage": "d4fb72f6-340e-b5af-5897-d5ab8bf7e937",
  "outputs": {

..blabla...

}

// running tf compliance I get

bash-5.0# terraform-compliance --debug -f git::ssh://[email protected]... -p state.out
terraform-compliance v1.3.7 initiated

Using remote git repository: :ssh://[email protected]...
ERROR: state.out is not a valid JSON file

This message seems to correspond to line: https://github.com/eerkunt/terraform-compliance/blob/02be1d2c4c98754f41998ccb2e9557708eac141b/terraform_compliance/common/readable_plan.py#L43-L45

wahlfeld10x avatar Nov 27 '20 06:11 wahlfeld10x

If processing pretty printed json plan files which contain multiple lines I notice this change https://github.com/eerkunt/terraform-compliance/pull/387 makes it process only the second line of the json file and get a JSON decode error.

timgates42 avatar Dec 16 '20 21:12 timgates42

That was definitely the problem. I will have a think about this for supporting the github actions & native cli usage.

Currently, the workaround for working on states is running like ;

$ terraform plan -out=state.out
$ terraform-compliance -p ./state.out -f ./scenarios

eerkunt avatar Jan 15 '21 10:01 eerkunt

State output file

  "format_version": "0.1",
  "terraform_version": "0.14.3",
  "values": {
    "root_module": {
      "child_modules": [
        {
          "resources": [
            {

I get

terraform-compliance v1.3.15 initiated

ERROR: state.out.json is not a valid terraform plan json output.

It seems the issue is in this code where it's not considering "child_modules" tag.

# Check if this is a state file            
if 'values' in data:                
     assert data['values']['root_module']['resources']

Code: https://github.com/terraform-compliance/cli/blob/ac843f3cda214b9c0d32be459fb623ccc18a9525/terraform_compliance/common/readable_plan.py#L76

Prazzy avatar May 26 '21 19:05 Prazzy

Hey, I had a similar error with my main.tfplan.json file because the file format wasn't UTF-8. I generated the file using terraform show -json main.tfplan > main.tfplan.json. After hours of agony, I noticed this LOC https://github.com/terraform-compliance/cli/blob/ac843f3cda214b9c0d32be459fb623ccc18a9525/terraform_compliance/common/readable_plan.py#L40 Checking the format of my main.tfplan.json, I realized it wasn't UTF-8. I then changed my command to output the json file to the following: terraform show -json main.tfplan | out-file -encoding ASCII main.tfplan.json and now it's working like a charm.

neuralNet007 avatar Feb 28 '22 07:02 neuralNet007