terraform-inventory
terraform-inventory copied to clipboard
Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error
After destroying our openstack instance with terraform v0.12.10 then terraform-inventory v0.9 crash with following message and our pipeline cannot continue:
Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
Of course, we understand terraform.tfstate is empty, but it did not happen with terraform v0.11.14 and terraform-inventory v0.8
Below is terraform.tfstate:
{ "version": 4, "terraform_version": "0.12.10", "serial": 12, "lineage": "24894aa7-228d-1dc3-0120-42a4be3cdc57", "outputs": {}, "resources": [] }
+1
+1
Looks like by default Terraform tries to directly read terraform.tfstate
which matches the output of terraform state pull
. However, terraform show -json
produces a different JSON, where resources
are nested under .values.root_module
, like the program expects for a 0.12+ file.
I was able to make it work by setting a var:
export TF_STATE=.
By pointing terraform-inventory to a directory instead of a file, it takes a completely different code path that properly utilizes terraform show -json
.
I am not sure what the best fix would be here. Maybe terraform-inventory should default to terraform show -json
at all times?
+1
thanks your reply. it works now.
---Original--- From: "Justinas Stankevičius"<[email protected]> Date: Thu, Nov 7, 2019 01:09 AM To: "adammck/terraform-inventory"<[email protected]>; Cc: "Comment"<[email protected]>;"paulmao1"<[email protected]>; Subject: Re: [adammck/terraform-inventory] Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error (#131)
Looks like by default Terraform tries to read terraform.tfstate which matches the output of terraform state pull. However, terraform show -json produces a different JSON, where resources are nested under .values.root_module, like the program expects for a 0.12+ file.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
And can you me a sample for playbook file.
The following is my file and get an error:
BR
Paul ------------------ 原始邮件 ------------------ 发件人: "81876776"<[email protected]>; 发送时间: 2019年11月8日(星期五) 中午1:23 收件人: "adammck/terraform-inventory"<[email protected]>;"adammck/terraform-inventory"<[email protected]>; 抄送: "Comment"<[email protected]>; 主题: Re: [adammck/terraform-inventory] Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error (#131)
thanks your reply. it works now.
---Original--- From: "Justinas Stankevičius"<[email protected]> Date: Thu, Nov 7, 2019 01:09 AM To: "adammck/terraform-inventory"<[email protected]>; Cc: "Comment"<[email protected]>;"paulmao1"<[email protected]>; Subject: Re: [adammck/terraform-inventory] Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error (#131)
Looks like by default Terraform tries to read terraform.tfstate which matches the output of terraform state pull. However, terraform show -json produces a different JSON, where resources are nested under .values.root_module, like the program expects for a 0.12+ file.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
The proposed workaround doesn't work for me for some reason: Terraform v0.12.18 terraform-ansible a408e896
Seems to work for me:
$ terraform version
Terraform v0.12.18
+ provider.digitalocean v1.12.0
$ terraform-inventory --list
Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
$ TF_STATE=. terraform-inventory --list
{"all":{"hosts":["185.14.185.236"],"vars":{}},"test1":["185.14.185.236"],"test1_0":["185.14.185.236"],"type_digitalocean_droplet":["185.14.185.236"]}
$ TF_STATE=. ansible -i $(which terraform-inventory) -u root -m ping all
185.14.185.236 | SUCCESS => {
"changed": false,
"ping": "pong"
}
terraform.tf
provider "digitalocean" {}
data "digitalocean_ssh_key" "j" {
name = "j"
}
resource "digitalocean_droplet" "test1" {
name = "test1"
region = "ams2"
size = "s-1vcpu-1gb"
image = "ubuntu-18-04-x64"
ssh_keys = [data.digitalocean_ssh_key.j.id]
provisioner "remote-exec" {
inline = [
"apt update",
"apt install -y python3",
]
}
}
Yep, sorry it appeared to be this issue #133
I'm getting the same error. The TF_STATE=.
workaround does not work for me. I tried terraform-inventory 0.9 and HEAD -> master as of Feb 29 (c7e468f33c6f4195cd9d8e97fa0e8d54b5c61c29).
$ terraform-inventory --inventory
Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
$ TF_STATE=. terraform-inventory --inventory
Error reading Terraform state: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
$ terraform-inventory --version
terraform-inventory version 0.9
$ terraform --version
Terraform v0.12.21
+ provider.aws v2.51.0
+ provider.random v2.2.1
$ cat terraform.tfstate
{
"version": 4,
"terraform_version": "0.12.21",
"serial": 32,
"lineage": "72c6e67a-e500-430a-341e-dab290bbf342",
"outputs": {},
"resources": []
}
Hi again everyone.
I have summarized the format differences below.
Terraform 0.11
A: state pull
& terraform.tfstate
{
"version": 3,
"terraform_version": "0.11.14",
"serial": 1,
"lineage": "3c9951c1-3229-ca05-2cf3-25d8472a9d51",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"digitalocean_droplet.hanginx.0": {...}
}
}
]
}
Terraform 0.12
B: show -json
{
"format_version": "0.1",
"terraform_version": "0.12.24",
"values": {
"root_module": {
"resources": [
{...}
]
}
}
}
C: state pull
& terraform.tfstate
{
"version": 4,
"terraform_version": "0.12.24",
"serial": 6,
"lineage": "1239f061-72f1-7e7b-161a-cb4bf72005f1",
"outputs": {},
"resources": [
{...}
]
}
~~The problem right now is that TI tries to use terraform show -json
but it can not actually parse that output (!!!)~~
Edit: the above statement is false. For 0.11 we support state pull
or terraform.tfstate
(the same format). For 0.12 we only support show -json
, but not terraform.tfstate
. Yet, we still try to read that file directly, because even if TF_STATE
is not set, we default to terraform.tfstate
.
I did not dig too deep here so I do not know if we actually have a hard requirement for something that is not present in state pull
, but present in show -json
or if it was just used as a new feature that could help us identify the version.
Anyway, I suggest to either drop support for 0.11 (0.12 has been out since May 2019 and people on 0.11 can keep using older versions of TI) OR detect version by parsing terraform version
, terraform.tfstate
, etc.
Having done that, stop calling show -json
at all and use state pull
that will match the format of terraform.tfstate
.
I suggest this in order to avoid having to maintain 3 parsers: one for 0.11, one for 0.12 show -json
, one for 0.12 state files.
@adammck we really need your thoughts here.
@AndiDog your input would also be appreciated.
It is not clear to me whether we should use show -json
or state pull
. The output of show -json
is well documented, but it does not match the format of state files. The easiest thing here would be to simply drop supporting raw state files and only allow using show -json
.
terraform state pull
on the other hand matches the state file, but is not documented well. However, the website indicates:
This is useful for reading values out of state (potentially pairing this command with something like jq).
So it seems that this is a valid use-case.
The error is clear enough: the state is empty. And it doesn't make sense to use terraform-inventory
on empty state, right? If people have a different opinion, we could change the error to a warning in case state is empty (and assume Terraform 0.12).
But the state file is not empty, it just contains a format we do not expect (B vs C in this comment). This is an obvious regression where previously pointing to either a directory or an individual state file worked, but now only a directory is processed correctly (and it is not even a default).
As I see it, out of the box (read: without pointing it to a directory via the env var) terraform-inventory 100% does not work with 0.12.
Understood now. Let me put this in a reproducible example:
$ rm -rf /tmp/example && mkdir /tmp/example && cd /tmp/example
$ cat >main.tf <<EOF
provider "null" {}
resource "null_resource" "example" {
provisioner "local-exec" {
command = "true"
}
}
EOF
$ terraform init
[...]
$ terraform apply -auto-approve
[...]
$ jq -c . terraform.tfstate
{"version":4,"terraform_version":"0.12.24","serial":1,"lineage":"3e8f9aa4-9daf-322e-e68f-dcaebf391f0b","outputs":{},"resources":[{"mode":"managed","type":"null_resource","name":"example","provider":"provider.null","instances":[{"schema_version":0,"attributes":{"id":"3973960162525722052","triggers":null},"private":"bnVsbA=="}]}]}
$ terraform show -json
{"format_version":"0.1","terraform_version":"0.12.24","values":{"root_module":{"resources":[{"address":"null_resource.example","mode":"managed","type":"null_resource","name":"example","provider_name":"null","schema_version":0,"values":{"id":"3973960162525722052","triggers":null}}]}}}
$ terraform show -json .
[...]
Plan read error: read .: is a directory
$ terraform show -json terraform.tfstate
{"format_version":"0.1","terraform_version":"0.12.24","values":{"root_module":{"resources":[{"address":"null_resource.example","mode":"managed","type":"null_resource","name":"example","provider_name":"null","schema_version":0,"values":{"id":"3973960162525722052","triggers":null}}]}}}
$ terraform-inventory --list
Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
$ terraform-inventory --list . ; echo
{"all":{"hosts":[],"vars":{}}}
$ TF_STATE=. terraform-inventory --list ; echo
{"all":{"hosts":[],"vars":{}}}
I suggest we drop 0.11 support and always call terraform show -json
- no implementation effort needed apart from removing lots of old code. With the current implementation, 0.12 format parsing has been working without issues since I implemented it. terraform show -json
gives the current state by default, and we should use that default as well. If TF_STATE
/TI_STATE
is defined explicitly, we can still pass it on to terraform show -json <argument>
(changing TF_STATE=.
to TF_STATE=terraform.tfstate
with a warning, because only terraform show -json terraform.tfstate
works fine).
I am having same issue in AWS. Everything worked great in terraform 11.
anyone already tested with terraform 0.13? asking before upgrading...
[UPDATE] I've upgraded to 0.13 and the issue is still the same and the workaround works even with 0.13. at least it's safe to upgrade.
I build terraform-inventory from source code
Same error:
terraform-inventory --list Error reading tfstate file: 0.12 format error: <nil>; pre-0.12 format error: <nil> (nil error means no content/modules found in the respective format)
terraform-inventory build from source.
Try on repo https://github.com/yandex-cloud/examples/tree/master/active-directory
$ terraform -version
Terraform v0.11.14
+ provider.yandex v0.46.0
$ terraform show -json .
Usage: terraform show [options] [path]
Reads and outputs a Terraform state or plan file in a human-readable
form. If no path is specified, the current state will be shown.
Options:
-module-depth=n Specifies the depth of modules to show in the output.
By default this is -1, which will expand all.
-no-color If specified, output won't contain any color.
$ terraform show -json terraform.tfstate
Usage: terraform show [options] [path]
Reads and outputs a Terraform state or plan file in a human-readable
form. If no path is specified, the current state will be shown.
Options:
-module-depth=n Specifies the depth of modules to show in the output.
By default this is -1, which will expand all.
-no-color If specified, output won't contain any color.
$ terraform-inventory --list
Error running `terraform show -json` in directory /home/user/examples/active-directory, exit status 1, falling back to trying Terraform pre-0.12 command
{"ad":["10.0.0.26"],"ad_0":["10.0.0.26"],"all":{"hosts":["10.0.0.26"],"vars":{}},"type_yandex_compute_instance":["10.0.0.26"]}
$ terraform-inventory --list . ; echo
Error running `terraform show -json` in directory /home/user/examples/active-directory, exit status 1, falling back to trying Terraform pre-0.12 command
{"ad":["10.0.0.26"],"ad_0":["10.0.0.26"],"all":{"hosts":["10.0.0.26"],"vars":{}},"type_yandex_compute_instance":["10.0.0.26"]}
$ TF_STATE=. terraform-inventory --list ; echo
Error running `terraform show -json` in directory /home/user/examples/active-directory, exit status 1, falling back to trying Terraform pre-0.12 command
{"ad":["10.0.0.26"],"ad_0":["10.0.0.26"],"all":{"hosts":["10.0.0.26"],"vars":{}},"type_yandex_compute_instance":["10.0.0.26"]}