Terraform: Plan shows outputs being removed when doing a target apply

Created on 16 Sep 2020  ยท  6Comments  ยท  Source: hashicorp/terraform

Terraform Version

Terraform v0.13.3
+ provider registry.terraform.io/-/aws v3.6.0
+ provider registry.terraform.io/-/null v2.1.2
+ provider registry.terraform.io/hashicorp/aws v3.6.0
+ provider registry.terraform.io/hashicorp/local v1.4.0
+ provider registry.terraform.io/hashicorp/null v2.1.2

Terraform Configuration Files

resource "aws_sqs_queue" "default" {
    name = "queue-1"
}

output "queue_id" {
    value = aws_sqs_queue.default.id
}

output "some_other_output" {
    value = "foo"
}

Expected Behavior

The plan should not show that it is removing other outputs. They are not actually being removed from the state file.

Actual Behavior

aws_sqs_queue.default: Refreshing state... [id=https://sqs.us-west-2.amazonaws.com/505834710180/queue-1]

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:
  - some_other_output = "foo" -> null


Warning: Resource targeting is in effect

You are creating a plan with the -target option, which means that the result
of this plan may not represent all of the changes requested by the current
configuration.

The -target option is not for routine use, and is provided only for
exceptional situations such as recovering from errors or mistakes, or when
Terraform specifically suggests to use it as part of an error message.

Steps to Reproduce

  1. terraform init
  2. terraform apply -target=aws_sqs_queue.default
bug confirmed v0.13 v0.14

Most helpful comment

Thanks for reporting this, @sidprak.

I've reproduced it on a current dev build of Terraform v0.14, with a slightly different configuration that avoids the need to have a working AWS account:

resource "null_resource" "foo" {
}

output "queue_id" {
  value = null_resource.foo.id
}

output "some_other_output" {
  value = "foo"
}

First I ran terraform apply with no arguments so that the resource and the two outputs would exist:

$ terraform apply

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

Terraform will perform the following actions:

  # null_resource.foo will be created
  + resource "null_resource" "foo" {
      + id = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

null_resource.foo: Creating...
null_resource.foo: Creation complete after 0s [id=8354822165448532473]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

queue_id = 8354822165448532473
some_other_output = foo

Then I ran terraform apply -target=null_resource.foo and saw the following output:

null_resource.foo: Refreshing state... [id=8354822165448532473]

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:
  - some_other_output = "foo" -> null


Warning: Resource targeting is in effect

You are creating a plan with the -target option, which means that the result
of this plan may not represent all of the changes requested by the current
configuration.

The -target option is not for routine use, and is provided only for
exceptional situations such as recovering from errors or mistakes, or when
Terraform specifically suggests to use it as part of an error message.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes


Warning: Applied changes may be incomplete

The plan was created with the -target option in effect, so some changes
requested in the configuration may have been ignored and the output values may
not be fully updated. Run the following command to verify that no other
changes are pending:
    terraform plan

Note that the -target option is not suitable for routine use, and is provided
only for exceptional situations such as recovering from errors or mistakes, or
when Terraform specifically suggests to use it as part of an error message.


Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

queue_id = 8354822165448532473
some_other_output = foo

Fortunately this plan output problem seems to just be cosmetic, because some_other_output is still present in the state after the apply step completed.

I expect this is caused by how we implemented the "Changes to outputs" part of the plan rendering so that we'd be able to include that even though Terraform 0.13 doesn't actually generate a plan for outputs in the same sense as it does for resources: Terraform implements that by capturing the full set outputs before, then calculating the plan, and then capturing the full set of outputs that resulted from the plan. Because the -target option excluded output "some_other_output" from the plan operation, it wasn't included in the set of outputs that resulted from the plan.

I expect we will not be able to fully address this at least until after some refactoring that is planned for Terraform 0.14, which will combine the refresh and plan walks together. That alone would not address this bug, but it will fix _one_ of the constraints that blocked us from making outputs participate fully in planning (generating explicit create, update, delete actions _during_ planning rather than merely diffing the before/after values). Once that refactoring is done we'll need to revisit that earlier decision and see if full planning of outputs is possible to implement, or if there are other blocks that might need to happen first.

To avoid showing misleading information in the meantime, we could potentially disable the "Changes to outputs" part of the plan rendering when targeting is in effect, knowing that the assumptions we make to generate those indications are violated by the -target option.

All 6 comments

Thanks for reporting this, @sidprak.

I've reproduced it on a current dev build of Terraform v0.14, with a slightly different configuration that avoids the need to have a working AWS account:

resource "null_resource" "foo" {
}

output "queue_id" {
  value = null_resource.foo.id
}

output "some_other_output" {
  value = "foo"
}

First I ran terraform apply with no arguments so that the resource and the two outputs would exist:

$ terraform apply

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

Terraform will perform the following actions:

  # null_resource.foo will be created
  + resource "null_resource" "foo" {
      + id = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

null_resource.foo: Creating...
null_resource.foo: Creation complete after 0s [id=8354822165448532473]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

queue_id = 8354822165448532473
some_other_output = foo

Then I ran terraform apply -target=null_resource.foo and saw the following output:

null_resource.foo: Refreshing state... [id=8354822165448532473]

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:
  - some_other_output = "foo" -> null


Warning: Resource targeting is in effect

You are creating a plan with the -target option, which means that the result
of this plan may not represent all of the changes requested by the current
configuration.

The -target option is not for routine use, and is provided only for
exceptional situations such as recovering from errors or mistakes, or when
Terraform specifically suggests to use it as part of an error message.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes


Warning: Applied changes may be incomplete

The plan was created with the -target option in effect, so some changes
requested in the configuration may have been ignored and the output values may
not be fully updated. Run the following command to verify that no other
changes are pending:
    terraform plan

Note that the -target option is not suitable for routine use, and is provided
only for exceptional situations such as recovering from errors or mistakes, or
when Terraform specifically suggests to use it as part of an error message.


Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

queue_id = 8354822165448532473
some_other_output = foo

Fortunately this plan output problem seems to just be cosmetic, because some_other_output is still present in the state after the apply step completed.

I expect this is caused by how we implemented the "Changes to outputs" part of the plan rendering so that we'd be able to include that even though Terraform 0.13 doesn't actually generate a plan for outputs in the same sense as it does for resources: Terraform implements that by capturing the full set outputs before, then calculating the plan, and then capturing the full set of outputs that resulted from the plan. Because the -target option excluded output "some_other_output" from the plan operation, it wasn't included in the set of outputs that resulted from the plan.

I expect we will not be able to fully address this at least until after some refactoring that is planned for Terraform 0.14, which will combine the refresh and plan walks together. That alone would not address this bug, but it will fix _one_ of the constraints that blocked us from making outputs participate fully in planning (generating explicit create, update, delete actions _during_ planning rather than merely diffing the before/after values). Once that refactoring is done we'll need to revisit that earlier decision and see if full planning of outputs is possible to implement, or if there are other blocks that might need to happen first.

To avoid showing misleading information in the meantime, we could potentially disable the "Changes to outputs" part of the plan rendering when targeting is in effect, knowing that the assumptions we make to generate those indications are violated by the -target option.

@apparentlymart thanks so much for the detailed explanation!

I have confirmed the new handling for planned output changes has taken care of this issue in 0.14.

Thanks!

To be clear, is this a deficiency just in the display of the command?

Or are the actual outputs (like use in a terraform remote state) removed?

Just the display as @apparentlymart described above.

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.

Was this page helpful?
0 / 5 - 0 ratings