Terraform plans now explain changes made outside configuration
Terraform 0.15.4 reports observed infrastructure changes separately from proposed actions. Refresh-only planning adds a review step before accepting those observations into state.
An unchanged configuration can still produce a Terraform plan with proposed changes. Someone may have changed a remote object directly, leaving Terraform to propose restoring the configured value. Without an account of what Terraform observed, the proposed action can look unprompted. Terraform 0.15.4, released on May 19, adds that missing explanation to plan output.
The release notes are explicit that Terraform already reads remote objects during planning by default. Detecting changes outside Terraform is not new. Reporting those detected changes as part of the plan result is new. This distinction matters because the additional section does not itself change the normal decision about which infrastructure actions to propose.
I appreciate Terraform's configuration model, but a plan needs to explain the difference between the infrastructure that exists and the infrastructure the configuration requests. Showing observations separately makes that model easier to reason about. A proposed correction becomes understandable when the reader can see the external change that prompted it.
A plan compares more than two documents
The planning documentation shipped with 0.15.4 describes reading current remote objects, comparing state and configuration, and proposing actions that make those objects match configuration. Those operations involve different kinds of information. The saved state records Terraform's previous understanding, the provider reports the current object, and configuration expresses the desired result.
Suppose a configured attribute requests one value, while a direct API operation changes the remote object to another. Terraform can observe the new value and still propose returning it to the configured value. Reporting only that proposal leaves the reader to reconstruct the intervening change. The new output can explain both the observation and the planned response.
The release notes also discuss a second case. An operator may intentionally change an object outside Terraform and then edit configuration to agree with it. Terraform may have no infrastructure correction to propose, but it can still report that it noticed the external change. An observation and a proposed action are therefore not interchangeable events.
This distinction prevents a misleading interpretation of the new section. A reported external change does not mean Terraform necessarily intends to undo it. The desired configuration still matters. The release describes the default reporting as informational and says an expected observation does not require an additional response merely because it now appears in the output.
Accepting observations becomes a plannable operation
The same release introduces -refresh-only as an alternative planning mode. Its purpose is to update Terraform state and root module output values to match changes made outside Terraform. It does not propose the ordinary configuration-driven changes that a normal plan would consider.
An interactive apply can select refresh-only mode directly. Terraform first generates the plan and presents its proposed state update for approval.
terraform apply -refresh-only
The release recommends this form for most situations that previously called for terraform refresh, because it provides a review opportunity before writing the observed changes to state. HashiCorp is retaining the existing refresh command. The difference is the explicit planning and approval step around the state update.
A saved plan allows observation and approval to happen in separate steps. The apply command then consumes the plan that the earlier command generated.
terraform plan -refresh-only -out=observed.tfplan
terraform apply observed.tfplan
The planning documentation describes -out as producing an opaque plan file that apply can execute. The file represents the generated plan, including its options and values. For refresh-only mode, the intended result is reconciliation of Terraform's records with observed objects, rather than an ordinary infrastructure change requested by configuration.
Accepting observations into state does not edit configuration. That follows from the mode's documented goal of updating state and root outputs. If configuration continues to request an older value, accepting an external observation does not by itself express a new desired value. A later normal planning operation still has configuration to compare against the remote object.
Refresh-only and skipping refresh have opposite purposes
The similarly named -refresh=false option solves a different problem. The planning documentation says it disables the default synchronization with remote objects before configuration changes are considered. That can reduce API requests, but also means the plan may omit external changes.
Refresh-only mode instead makes those observations the purpose of the operation. The documentation disallows combining it with -refresh=false, because doing so would disable the work the mode exists to perform. Refresh-only is also mutually exclusive with the other planning modes, including destruction.
These distinctions are useful for automation authors. A system that needs to record observed changes should not treat a flag that skips observation as an optimization of the same operation. The two options change different parts of the plan's meaning, despite sharing the word refresh.
I consider the reviewable state update the more consequential addition here. Visible drift reporting explains a normal plan. Refresh-only mode also provides a direct operation for accepting a changed understanding of existing infrastructure, with a plan that can be examined before state changes.
The release includes support for the refresh-only option in the remote backend's Terraform Cloud plans and applies. That extends the same distinction to hosted operations. The important result remains specific: Terraform can show what it observed, and the operator can approve recording those observations without bundling that decision with configuration-driven infrastructure actions.