Terraform JSON plans report root output changes
Terraform 1.0.5 adds planned output actions to the JSON UI stream. A plan can now explain output changes even when its resource counts are all zero.
A plan with no resource operations can still change what a Terraform configuration exports. Removing an output declaration, for example, changes the root module's outputs without necessarily asking a provider to modify an object. Terraform 1.0.5, released on August 18, adds output-change summaries to terraform plan -json so that its structured UI can represent this part of the plan.
The release describes the correction as bringing JSON logs into parity with the human-readable interface. That is an important distinction from adding new planning behavior. Terraform already has the output changes in its plan. The missing step was communicating their summary through the machine-readable stream.
I value Terraform's configuration abstraction partly because modules can expose a deliberate interface to their callers. Outputs are part of that interface. An automated summary that reports only resource operations can omit a change that matters to the people or software consuming the configuration's results.
Zero resource changes do not describe the entire plan
Alisdair McDiarmid's pull request 29312 includes a test that makes the omission concrete. The test constructs a plan with no resource changes and several root output entries. It expects the JSON view to emit a resource change_summary with all counts zero, followed by a separate outputs message.
The output entries exercise different actions, including noop, create, delete, and update. This matters because an outputs message is not itself proof that every entry changes. A consumer needs to read each entry's action. Treating the number of entries as the number of changed outputs would count the no-operation entry incorrectly.
The implementation adds this message after the resource change summary. It selects root module outputs from the plan's output changes, then constructs a map keyed by output name. Child-module output entries are filtered out of this particular summary. An integration should therefore interpret it as the root configuration's output interface, not a complete inventory of every internal module output.
This gives a more precise account of a plan's result. Resource counts describe planned operations on managed objects. Output actions describe changes to the values the root module exposes. Both can matter to a review even when only one involves a provider operation. A summary that uses resource counts as its sole definition of meaningful change would lose that distinction. The separate output message lets consumers retain it without changing the meaning of the existing resource counters.
Planned outputs and applied values have different fields
The patch extends an existing JSON output representation instead of inventing an unrelated message type. It adds an optional action field and makes type and value optional. The code uses the latter fields for applied output values, while planned output entries contain the action and sensitivity flag.
The following excerpt shows the shape of the planned-output payload. A complete UI message also has the stream's common metadata fields.
{
"type": "outputs",
"outputs": {
"endpoint": {
"action": "update",
"sensitive": false
}
}
}
The example deliberately contains no endpoint value. The planning summary communicates the output action without embedding a before-and-after value comparison. A consumer cannot assume every outputs entry always contains a value simply because earlier applied-output messages included one.
That difference follows the operation's meaning. A plan reports what will happen to the output. After a successful apply, an output message can report the resulting typed value. The same message family serves both uses, with fields that identify which information is available.
The documentation changes in the pull request retain the sensitive flag for both forms. They also warn that sensitive applied outputs still contain their values in the structured data. Integrating software must respect the flag when presenting those values. Omitting values from the planned summary does not change the handling required for applied output data.
Detailed comparisons remain in the plan representation
The pull request explains why it does not include before-and-after values in the stream. That level of detail belongs in the JSON plan output from terraform show -json. A summary event can identify an output and its action without taking on the job of representing the whole plan.
An integration can obtain both kinds of information through a saved plan:
terraform plan -json -out=change.tfplan
terraform show -json change.tfplan
The first command provides the structured UI stream and saves the generated plan. Running the second asks Terraform for a JSON representation of that saved plan. The two outputs have different formats and purposes, even though both use JSON and concern the same planning operation.
I prefer this division because a progress display and a detailed review have different information requirements. A stream can report that a named output will disappear. A review of the exact value changes can use the plan representation without requiring every UI event to duplicate it.
The practical consequence of 1.0.5 is a more complete structured summary. Consumers must accommodate the optional value fields and inspect output actions, but they can now explain plans whose externally visible result changes while every resource-operation count remains zero.