FR
live

Terraform 1.17 adds -minimal-refresh to speed up plans and graduates Policy to GA

On October 7, 2026, HashiCorp published Terraform 1.17.0-rc1 with a -minimal-refresh planning option that only refreshes resources with proposed changes, support for variables in provider requirements, and the general availability of Terraform Policy. A release candidate to test on large estates, not yet to roll out everywhere.

Surveyor’s theodolite on a tripod in a dark empty construction site, a single amber spirit-level bubble glowing in its eyepiece.

On October 7, 2026, HashiCorp published Terraform 1.17.0-rc1, the first release candidate of version 1.17. It ships a -minimal-refresh planning option that only refreshes resources with proposed changes, support for variables in provider requirements, and the general availability of Terraform Policy. Why it matters: slow terraform plan runs on large estates are a recurring complaint, and this release candidate attacks that bottleneck directly.

What -minimal-refresh changes

The historical behavior of terraform plan is to refresh the state of every resource before computing the diff. On an estate of several hundred resources, that refresh phase dominates the runtime, even though most resources have not moved since the last apply.

The -minimal-refresh option inverts the logic: it only refreshes resources that have proposed changes. In practice, when you change a single resource in a plan that counts hundreds, the refresh focuses on what is actually affected instead of re-querying the whole cloud provider. It is an optimization aimed at the most common case — a small change inside a large state.

The nuance to understand: -minimal-refresh is an opt-in that changes the scope of the refresh, not the semantics of the plan. A plan produced with this option may miss external drift on resources it does not touch, because they are not refreshed. It is a trade-off between speed and exhaustiveness, to be judged against whether your estate tolerates a partial refresh.

Why refresh costs so much

Refresh is the phase where Terraform queries each provider for the real state of resources, to detect drift between the declared state and reality. That work is essential to a reliable plan, but it is expensive: every API call to a cloud provider takes time, and on a large estate, the accumulation of those calls dominates plan time.

The problem is made worse by a simple fact: most of the time, nothing has changed. When you modify a single resource in a five-hundred-resource estate, refreshing the other four hundred and ninety-nine only serves to confirm that they have not moved. That is exactly the waste -minimal-refresh removes, by concentrating work where the plan proposes a change.

The gain depends on the estate. On a state where changes are rare and localized, the difference can be dramatic; on an estate where everything moves every iteration, the option buys almost nothing, since everything would be refreshed anyway. It is an optimization for the common case, not a magic wand — and it assumes you accept that external drift on un-refreshed resources stays invisible until their next refresh.

Variables in provider requirements

The second substantive addition is support for variables and locals in provider requirements. Until now, the required_providers block demanded literal values: the source and version of a provider were frozen in code, which made it hard to reuse the same module in contexts where the version or origin of a provider had to vary.

You can now parametrize those requirements, which unlocks two scenarios. The first is module reuse: a module can require a provider whose version is injected by the caller rather than hard-coded. The second is multi-environment management: a single configuration can point at a different provider version per environment without duplicating code. It is a long-standing community request, tracked as issue #39153.

Terraform Policy goes GA

The third pillar of the release is the general availability of Terraform Policy. The -policies flag on plan, apply and query no longer requires an experimental build or the -allow-experimental-features flag. Concretely, teams can now evaluate their resources against policies during plan and apply, without enabling an experimental mode.

The terraform query command evaluates resources discovered by list blocks and reports human-readable or JSON results. This is the missing piece for native policy-as-code in Terraform, without depending on a third-party tool: the compliance rules live in the same place as the infrastructure they govern.

The rest of the release is quieter but useful: terraform init logs are enriched with provider versions, which helps diagnose version drift between environments.

Testing and ephemeral resources move forward

Two quieter improvements deserve the attention of teams that automate. The first: terraform test gains mock_provider support for ephemeral resources. Concretely, you can test a configuration that uses these resources without actually creating them, by simulating the provider. It is another step toward reproducible, fast infrastructure tests, rather than validations that demand a real cloud account.

The second concerns the handling of ephemeral resources themselves. Terraform now surfaces diagnostics raised when renewing an ephemeral resource — warnings that were previously dropped silently. A renewal error that went unnoticed could produce downstream failures that were hard to explain; making it visible simplifies diagnosis. Add to that a robustness fix: pow and log no longer panic Terraform when their result is not a number.

These changes are quiet, but they reinforce the same idea as the rest of the release: making Terraform more predictable and observable in real-world scenarios, where ephemeral resources and automated tests have become the norm.

A contract change to watch

The release candidate also introduces a detail worth noting for integrations: the JSON output of the version command now includes a format_version field. HashiCorp frames it as a guardrail for future changes to the JSON format, on the assumption that existing tooling ignores unknown fields. It is a signal for teams that parse that output: plan to follow format_version rather than assume the structure is frozen.

The release candidate status should also temper enthusiasm. 1.17.0-rc1 is not a stable release: it exists to test the new features before the final cut. Fixes on the 1.16 branch continue in parallel — 1.16.5 shipped on September 30, 2026 with two crash fixes. Production teams should stay on 1.16 and reserve 1.17 for test environments.

What still needs to land

A release candidate is, by definition, unfinished. The two headline features — -minimal-refresh and Policy GA — are present and testable, but the final stable cut is where the edge cases shake out. Teams that parse the version JSON should already be planning for the format_version field, since it signals that the format will evolve deliberately rather than stay frozen.

Meanwhile the 1.16 branch keeps receiving fixes: 1.16.5, published on September 30, 2026, patched two crashes — one on a tainted instance state without a valid status, the other on a nil resource identity during delete. That is the usual reminder that stable releases keep getting care while 1.17 matures.

Verdict

If your terraform plan runs are slow on a large estate, the -minimal-refresh in 1.17 is the feature to test first: it attacks the refresh phase that dominates your plan times, provided you accept a partial refresh on untouched resources. If you were waiting for native policy-as-code, the GA of Terraform Policy is the signal to start writing your policies and wiring them into plan and apply. But do not roll out a release candidate into production: validate the behavior in pre-production, watch the format_version field if you parse the JSON output, and switch only once the stable 1.17 release ships.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

GitHub stacked pull requests go GA with 9% more merged code

GitHub announced general availability for stacked pull requests, which split a large change into small, independently reviewed pull requests that merge together at the end. If your branches keep blocking each other, GitHub’s numbers — 9% more merged code and 5% faster time-to-merge — justify adopting them now.

← Back to the feed

Type at least two characters.

↑ ↓ navigate ↵ open esc dismiss