terraform icon indicating copy to clipboard operation
terraform copied to clipboard

plan -detailed-exitcode -destroy return "2" when nothing to destroy

Open next-jesusmanuelnavarro opened this issue 5 years ago • 9 comments

Terraform Version

$ terraform -v
Terraform v0.12.15

Expected Behavior

as per help, terraform plan -detailed-exitcode should return:

                      0 - Succeeded, diff is empty (no changes)
                      1 - Errored
                      2 - Succeeded, there is a diff

Actual Behavior

terraform plan -detailed-exitcode -destroy returns '2' on already destroyed infra.

Steps to Reproduce

On an already destroyed infra (I'm using shared state/lock on S3/DynamoDB):

  1. terraform init
  2. terraform plan -detailed-exitcode -destroy -out=./planfile
  3. $?. It returns 2 code, and the following message to stdout:
------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Then, upon acting on the plan...

$ terraform show ./planfile
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Additional Context

This behaviour has changed a bit since Terraform v0.12.10: while the plan step produced the same stdout, and exit code, terraform show offered a different message:

$ terraform show ./planfile
This plan does nothing.

References

This behaviour is neither the first, nor the second, nor the third time it gets described:

  • #16055
  • #18453
  • #18224

next-jesusmanuelnavarro avatar Nov 15 '19 09:11 next-jesusmanuelnavarro

Hey @danieldreier I'm a new contributor and I'm willing to contribute on this. Please advise if I can proceed to start working on it. Thanks

MartinKaburu avatar Nov 21 '19 22:11 MartinKaburu

I'm experiencing the same issue on terraform plan -detailed-exitcode -destroy this is my output:

An execution plan has been generated and is shown below.

Resource actions are indicated with the following symbols:



Terraform will perform the following actions:



Plan: 0 to add, 0 to change, 0 to destroy.

script returned exit code 2

jjno91 avatar Jul 17 '20 18:07 jjno91

Hello same issue


An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.```

echo $?
2

on terraform 0.13.0  on 0.12.26 it was OK 

Jean-Mercier avatar Sep 04 '20 15:09 Jean-Mercier

I can confirm this bug is still present on terraform v0.13.0.

next-jesusmanuelnavarro avatar Sep 15 '20 07:09 next-jesusmanuelnavarro

I can confirm it is present in terraform v0.13.5. We had one check that flagged a change in a datasource which caused exit code 2

corey-hammerton avatar Jan 14 '21 14:01 corey-hammerton

Same here with Terraform v.0.15.0.

Joorem avatar Apr 26 '21 12:04 Joorem

I haven't been able to reproduce this on any of the stated versions, or latest, with trivial config. I'd be grateful if someone could provide a reproduction case.

Terraform is returning 2 from plan -detailed-exitcode -destroy because it considers the plan applyable, but it is not showing those applyable actions to the user. The bug here is either that an empty plan is wrongly considered applyable, or that the UI output is missing information.

We can construct a case like this with config based on https://github.com/hashicorp/terraform/issues/16055. Here a destroy plan with output changes is being rendered to the user as an empty plan, but detected by Terraform as applyable.

Config

data "external" "foo" {
  depends_on = [null_resource.test]
  program = ["bash", "${path.module}/test.sh"]
}

resource "null_resource" "test" {
}
output "foo" {
  value = data.external.foo.result["foo"]
}

Steps

  1. terraform init
  2. terraform plan -detailed-exitcode -destroy

Result

Exit code 2.

Output:


Changes to Outputs:

You can apply this plan to save these new output values to the
Terraform state, without changing any real infrastructure.

───────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so
Terraform can't guarantee to take exactly these actions if you run
"terraform apply" now

(Note the dangling newline at the beginning of this output - the plan renderer does not anticipate the case in which an applyable plan has no initial segment describing resource changes.)

Plan

{
  "format_version": "1.1",
  "terraform_version": "1.3.0-dev",
  "planned_values": {
    "root_module": {}
  },
  "output_changes": {
    "foo": {
      "actions": [
        "delete"
      ],
      "before": null,
      "after": null,
      "after_unknown": false,
      "before_sensitive": false,
      "after_sensitive": false
    }
  },
  "configuration": {
    "provider_config": {
      "external": {
        "name": "external",
        "full_name": "registry.terraform.io/hashicorp/external"
      },
      "null": {
        "name": "null",
        "full_name": "registry.terraform.io/hashicorp/null"
      }
    },
    "root_module": {
      "outputs": {
        "foo": {
          "expression": {
            "references": [
              "data.external.foo.result[\"foo\"]",
              "data.external.foo.result",
              "data.external.foo"
            ]
          }
        }
      },
      "resources": [
        {
          "address": "null_resource.test",
          "mode": "managed",
          "type": "null_resource",
          "name": "test",
          "provider_config_key": "null",
          "schema_version": 0
        },
        {
          "address": "data.external.foo",
          "mode": "data",
          "type": "external",
          "name": "foo",
          "provider_config_key": "external",
          "expressions": {
            "program": {
              "references": [
                "path.module"
              ]
            }
          },
          "schema_version": 0,
          "depends_on": [
            "null_resource.test"
          ]
        }
      ]
    }
  },
  "relevant_attributes": [
    {
      "resource": "data.external.foo",
      "attribute": [
        "result",
        "foo"
      ]
    }
  ]
}

In this case, however, it's not clear to me whether the output action should exist at all and whether this plan should be considered applyable. Opened https://github.com/hashicorp/terraform/pull/31471 to try to deal with this side of the issue.

kmoe avatar Jul 19 '22 13:07 kmoe

I haven't been able to reproduce this on any of the stated versions, or latest, with trivial config. I'd be grateful if someone could provide a reproduction case.

I created a simple test case at https://github.com/jmnavarrol/terraform-issue-23387.

Some things to note:

  • Output management seems to have changed (again) since the 0.x.x days when this bug was first opened. I remember that, back then, outputs after a destroy didn't show anything while, nowadays, as per my test case, a second destroy after a successful one shows a message:
    1. terraform apply
    2. terraform destroy
    3. terraform destroy (again, which should do nothing)
$ terraform destroy

Changes to Outputs:
  - hello_world = "Hello from project terraform-issue-23387" -> null

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes


Destroy complete! Resources: 0 destroyed.
$

The case above aligns with the findings from @kmoe: since there's a (fake) output change, it's no wonder rc is 2 instead of the expected 0.

Just like @kmoe, if I comment in the output directive, terraform plan -detailed-exitcode returns error code '0', as expected, both at current 1.2.6 version as well as older 0.x.x ones.

So, my impression is that all these cases using 0.x.x versions with no visible output did in fact change the state in non-obvious ways, just like @kmoe has discovered; it's only that now at least in some of the cases the (unexpected/fake change) became obvious.

jmnavarrol avatar Aug 03 '22 12:08 jmnavarrol

Thanks for the test case, @jmnavarrol. I believe this is fixed in https://github.com/hashicorp/terraform/pull/31471, which was released in v1.3.0-alpha20220803. Could you try it out with https://releases.hashicorp.com/terraform/1.3.0-alpha20220803/ and let me know if it behaves as you would expect?

kmoe avatar Aug 09 '22 15:08 kmoe

Thanks for the test case, @jmnavarrol. I believe this is fixed in #31471, which was released in v1.3.0-alpha20220803. Could you try it out with https://releases.hashicorp.com/terraform/1.3.0-alpha20220803/ and let me know if it behaves as you would expect?

Didn't get in time to test your alpha release but I can say this seems fixed on current Terraform 1.3.4 version (I updated my test case at https://github.com/jmnavarrol/terraform-issue-23387).

Both a simple (second time) terraform destroy and terraform plan -detailed-exitcode -destroy now return zero as expected.

Thanks a lot for this great job!!!

jmnavarrol avatar Nov 13 '22 14:11 jmnavarrol

I think this issue could be closed. I tested again on my repository with Terraform version 1.6.2 and I couldn't reproduce this bug anymore.

jmnavarrol avatar Oct 21 '23 11:10 jmnavarrol

@jmnavarrol Thank you!

crw avatar Oct 23 '23 17:10 crw

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.

github-actions[bot] avatar Dec 07 '23 02:12 github-actions[bot]