Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"terraform plan" should consider refresh updates as needing to be applied #15419

Closed
apparentlymart opened this issue Jun 28, 2017 · 9 comments
Closed

Comments

@apparentlymart
Copy link
Contributor

With the addition of data sources in 0.7, it became possible that a terraform plan -out=tfplan could discover that data source changes are present -- possibly then causing output changes -- even if no resources need to be changed as a result.

Currently there is a hole in the workflow where it's tricky to apply such updates.

Along with the existing logic in the plan command that checks if the diff is non-empty, we should also check to see if the state changed during the refresh step. If any changes are present, we should produce a special sort of plan that includes no changes but includes the updated state:

$ terraform plan -out=tfplan
(usual output from the refresh step elided)

Infrastructure is up-to-date, but changes were detected to data sources or resources
during refresh.

These changes have not yet been recorded in the persistent state. To synchronize the
state with the changes to real-world resources, and update any output whose value
depends on these changes, run the "apply" command:
    terraform apply tfplan

This plan will make no changes to real resources.

It's interesting to note here that it feels a little weird to not spell out exactly which changes this will make, but yet it's completely consistent with the amount of information we give about updates when there are resource changes to apply. Along with this, we may wish to consider including changes to outputs in the diff in both cases, so that people with configurations that are consumed downstream by terraform_remote_state can feel more confident about the impact of their changes on those downstream consumers.

Changes to outputs:
      aws_vpc_id:    "vpc-12345" => "vpc-54321"
      aws_subnet_id: "subnet-12345" => <computed>
@apparentlymart
Copy link
Contributor Author

Here's a more recent UI mock which incorporates this idea, along with some other potential changes including #17034:

Mock screenshot of "terraform apply" with refresh updates explicitly shown, and other features

The main interesting things shown in this mock are:

  • Explicit warning if any changes are detected when Terraform refreshes existing resources. This serves as context for understanding the plan below it, and draws attention to changes that may not have been intended.
  • Data resources are read during the plan step, per Data Resource Lifecycle Adjustments #17034.
  • Terraform includes in the plan output any data resource whose values have changed since the last apply, as additional context to understand the origin of other changes.
  • Changes to output values are shown as part of the plan.
  • This also includes the new structured diff output format previously discussed in Improving perception of changes when showing diff #15180.

The Terraform team at HashiCorp is currently focused on configuration language improvements and so isn't currently working on the changes shown here, but this mock was created as part of exploring potential future needs during the configuration language improvements design phase.

@ocervell
Copy link

Looks great ! Any idea on when this will be released ?

@ktham
Copy link

ktham commented Aug 22, 2019

@apparentlymart with TF 0.12 and hcl2 now out, is this issue back on your guys' radar?

The issue I'm running into is that adding additional output variables will not get placed in Terraform state because Terraform Enterprise will report that there are "no changes to be made" after executing a terraform plan.

This is problematic when I want to add output variables in one TFE workspace to be consumed in a different TFE workspace, but without changing any existing resources in the former.

Terraform Enterprise does not give an option to execute a terraform refresh so what needs to happen is for terraform plan to actually update Terraform State during this planning phase even if no actual resources are being changed.

@qrilka
Copy link
Contributor

qrilka commented Jan 15, 2020

@ktham did you find any workaround for this?

@ktham
Copy link

ktham commented Feb 4, 2020

@qrilka The only workaround I can think of is to force terraform to create a new resource

resource "null_resource" "no_op" {
  // TODO: remove me
}

@qrilka
Copy link
Contributor

qrilka commented Feb 4, 2020

In the end we had some real changes in the state. Thanks for this hint @ktham

@red8888
Copy link

red8888 commented Oct 30, 2020

bump. I rely heavily on outputs and imports but now im thinking I made the wrong decision because of this issue.

Its scary to not see what the changed outputs will be before running apply when you know other workspaces depend on those output values.

I eventually wanted to switch to enterprise so I could use run triggers but not before I can see output changes as a diff in plan output

@vongohren
Copy link

How are we doing on this issue? The refresh works fine, but it does seem like a hack?

@apparentlymart
Copy link
Contributor Author

apparentlymart commented May 13, 2021

Hi all!

We've been gradually working through the various parts of this (the things that my earlier mock screenshot showed) over some recent releases:

  • v0.13.0 changed the rules for what constitutes an "applyable" plan to include plans that only change the root module outputs, meaning that adding, removing, or changing output blocks (or the values they depend on) could be planned and applied in a similar way to actions on managed resources.
  • v0.14.0 introduced the "concise diff" mechanism where Terraform will not include most unchanged arguments in the plan output, instead marking them with a placeholder comment, in order to make it easier to scan the ones that are changing.
  • The forthcoming v0.15.4 should introduce the "Values changed outside of Terraform" note which lets you see what upstream changes Terraform was already detecting during its refresh step but previously keeping silent about.

Since this original proposal and mock some research led to some adjustments to the design which mean that this result doesn't exactly match what I originally proposed back in 2017.

The most notable difference is that I had originally called for any changes detected during refresh to be "needing to be applied", but when we tried prototyping that we realized that more subtlety was warranted: there are lots of configurations already out there which expect some changes to objects detected during refresh but they are immaterial because they don't have any externally-visible side-effect. With that in mind, the rule we settled on is that a plan is "applyable" if it contains at least one planned action for either a managed resource or for a root module output value. Terraform will still detect and report other changes as part of the plan, but by default it won't prompt for whether you want to apply those, and will instead continue to exit with the "No changes" message as before.

However, the use-case of having intentionally made changes outside of Terraform that you now want to incorporate still remained to be solved, and so as a compromise to meet that we've introduced a new planning mode -refresh-only, which effectively serves as a plannable replacement for terraform refresh. We don't plan to remove terraform refresh any time soon, but we do intend to recommend using terraform apply -refresh-only instead in most cases so you can verify that the detected changes are what you expected before committing them to a new state file snapshot. The refresh-only planning mode is not yet available in Terraform Cloud at the time I'm writing this comment, but the Cloud team has been working on that concurrently with us to make sure it'll be available to Cloud users very soon.

Another more subtle difference is that Terraform v0.14.0 removed the separate "refresh" phase from Terraform and instead incorporated it as just another part of planning each managed resource instance. That was important to fix some earlier design flaws that prevented Terraform from properly respecting dependencies, but it also meant that my conception in the mock screenshot of there being separate "Refreshing existing resources" and "Preparing execution plan" phases didn't pan out. Instead, the "Values changed outside of Terraform" has become just another part of the plan, because the two are no longer separable. A nice unintended side-effect of that, though, is that if you save a plan containing refresh-detected changes and run terraform show on it then you'll see those same changes reflected there too: those changes are as much a part of the plan as the planned actions are, and so they travel together from the plan step to the apply step.

The final difference I'll note is the subtle change in tone of the message. When I mocked it before I presented "Values changed outside of Terraform" as a Warning, but during our research for this feature we realized that this was too severe. There are lots of situations where changes outside of Terraform are an expected part of a workflow, and our goal for those cases is only to have Terraform acknowledge that it saw those changes and took them into account, not to suggest that those changes are necessarily "bad". Consequently, in the final implementation we've landed for v0.15.4 this message is instead a "Note: ", which is not a message type we've really used in Terraform before, but we hope it will serve to make that extra part of the plan output stand out more when it's present (making it harder to confuse it with the similar-looking planned actions output) while leaving it ultimately up to the user to decide whether they should take any action in response to it or just treat it as a confirmation of what they already expected to have happened.

Since this issue is now nearly four years old and we've attended to all of the main use-cases that motivated it, I'm going to close this issue now. If you find yourself here because you have feedback about any of the changes I've described above that contributed to this issue eventually being closed then please do open a new bug report or feature request issue to discuss what you are seeing, because it'll be easier to have separate conversations about specific feedback than to try to talk about this entire series of changes all in one flat GitHub thread. Thanks!

@hashicorp hashicorp locked as resolved and limited conversation to collaborators May 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants