FR
live

Terraform 1.17 graduates policy-as-code out of experimental

On October 21, 2026, HashiCorp shipped Terraform 1.17.0, which makes Terraform Policy generally available in the CLI with no experimental build or dedicated flag, and adds the -minimal-refresh planning option plus variables in provider requirements. For IaC teams, it is the moment to decide: adopt native policy in the plan, or stick with OPA/Conftest and Sentinel.

A metal clipboard on dark slate with a heavy rubber approval stamp resting on it, one small amber ink pad glowing beside it.

October 21, 2026. HashiCorp ships Terraform 1.17.0, graduating Terraform Policy to general availability — the -policies flag becomes usable on plan, apply, and query with no experimental build. October 28, 2026. The 1.17.1 patch release follows. 1.17. The line is rebuilt with Go 1.26.10, which stops trusting compromised eMudhra intermediate CAs. Why it matters: policy-as-code enters the default plan path, and that is an architecture decision as much as a CLI upgrade.

The substance: policy joins the plan

Terraform Policy is not a brand-new feature — it already existed in experimental form. What changes is the status. Until now, evaluating a policy required an experimental build and the -allow-experimental-features flag. Terraform 1.17 removes that constraint: -policies is directly available on plan, apply, and query.

The consequence is concrete for an infrastructure team. A policy is written in HCL, the same language as the rest of the configuration, and evaluated at plan time. A rule that forbids public S3 buckets, or requires a cost tag on every resource, becomes a plan failure before infrastructure changes. The framework and language are documented at developer.hashicorp.com/terraform/policy.

bash
# Evaluate a policy at plan time (GA, no experimental flag)
terraform plan -policies=./policies

# Query resources discovered by list blocks
terraform query -policies=./policies

Query policies can evaluate resources discovered by list blocks and report results in human-readable or JSON form — which makes them automatable in a pipeline.

A performance lever: -minimal-refresh

The second useful addition has nothing to do with policy, but it answers a recurring complaint from teams running large state files. The -minimal-refresh option limits refresh to resources that have proposed changes, instead of refreshing every resource in state.

On a state with tens of thousands of resources, the difference is measured in minutes of plan time saved. It is a simple lever, no migration, and worth testing first for teams whose plans drag.

bash
# Cut plan time on large states
terraform plan -minimal-refresh

Providers become parameterizable

The third change touches code structure. Terraform 1.17 now accepts variables and locals in the required_providers block. You can parameterize a version constraint or source address instead of hardcoding it.

hcl
locals {
  aws_provider_version = ">= 5.0.0, < 6.0.0"
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = local.aws_provider_version
    }
  }
}

This is a maintainability win for organizations driving many modules from a central file: the version policy is defined in one place and propagates.

What hides in the fixes: a revoked CA trust

The release notes carry a detail the headlines miss. Terraform 1.17 is rebuilt with Go 1.26.10, which removes trust for certificates issued by a set of compromised eMudhra intermediate CAs, tracked as CVE-2026-111943.

The scope is narrow but real: if a provider registry endpoint or a provider API in your environment relied on those authorities, the connection will fail after the upgrade. It is the kind of change that never shows up in the functional diff and surfaces in production — which is why reading the Go line matters as much as the HCL line.

Two quieter fixes complete the picture. The pow and log functions no longer panic when the result is not a number: they now raise a clear error instead of returning an infinity that nothing downstream could use. And diagnostics raised while renewing an ephemeral resource are now surfaced instead of silently swallowed — some teams will see warnings that were previously hidden.

The testing framework moves with it: mock_provider now supports ephemeral resources, letting module authors test configurations that rely on that mechanism without real infrastructure. It is a detail for module writers more than operators, but it signals the direction of the 1.17 line: consolidate recent features rather than introduce new ones.

The real question: where should policy live now?

The GA of Terraform Policy reopens an architecture question many teams thought settled. Three options coexist, and they do not do the same job.

Terraform Policy evaluates policy in the CLI, at plan time, in the same language as the infrastructure. Its advantage is immediacy: no third-party service, no separate engine. Its limit is scope: it only sees what Terraform sees.

OPA/Conftest evaluates policy over any data — Rego applied to plans as JSON. Its advantage is generality and ecosystem: the same rules can serve Terraform, Kubernetes, and other formats. Its limit is integration: you must wire the pipeline yourself.

Sentinel, HashiCorp’s long-standing policy system, lives mainly in Terraform Cloud and Enterprise — not in the open-source CLI. That is the difference to remember: Terraform Policy brings to the free CLI a capability that was, until now, reserved for the commercial offering.

The choice depends on estate size and where policy must live. A single-cloud, single-tool team will find in Terraform Policy a native policy with no moving parts. An organization governing multiple tools and formats will keep OPA/Conftest as the single policy layer and use Terraform Policy at most as a first-line check.

For most teams the honest answer is that they need both layers. Terraform Policy catches the mistakes that live in the plan itself — a resource that violates your own rules. OPA/Conftest catches the mistakes that live across the whole stack — a policy that must hold the same way in Terraform, Kubernetes, and the registry. The two do not compete as much as they slot into different levels of the control plane.

The fork’s context: OpenTofu did not wait

It is impossible to discuss Terraform in 2026 without the OpenTofu counterpoint. The fork was born in 2023 out of HashiCorp’s decision to move Terraform under the Business Source License (BSL). This blog has already documented OpenTofu’s rise as an alternative, including its 1.13 line and its approach to state.

Terraform Policy is a HashiCorp differentiator: a governance capability built into the plan, where OpenTofu bets on compatibility and native state encryption. For a decision-maker, the question is not only technical — it is also about which side accumulates governance features in the future. GA policy-as-code in the free CLI is a clear signal that HashiCorp wants to keep governance in its orbit, even in open source.

The asymmetry is worth watching on the pricing axis too. Terraform Policy runs in the free CLI, but the deeper governance story — policy at scale, across teams and organizations — is where HashiCorp points its commercial platform. Free policy in the CLI is an on-ramp, not the destination.

Verdict

Terraform 1.17 is minor in number, major in signal: policy-as-code enters the CLI by default, and the upgrade is low-risk — no breaking changes are called out in the changelog.

If you already run Terraform, move to 1.17 without delay: the upgrade is benign (terraform init -upgrade and re-run your plan/apply pipeline), and you pick up -minimal-refresh and the Go fix for the eMudhra authorities along the way. If governance is your topic, test Terraform Policy on a real plan before choosing: write a simple rule (no public buckets, mandatory cost tag) and measure whether native policy covers your need or whether OPA/Conftest remains the single layer you need. If you are on OpenTofu, this release is not for you, but it is one to watch: it shows where HashiCorp is concentrating its governance effort, and that gap widens with every release. The rule to remember: a policy evaluated in the plan beats a policy evaluated after the fact — and the plan, now, does it without a caveat.

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 rebuilds its Git storage to absorb 5,000 agents on a single repository

On November 5, 2026, GitHub detailed “Project Rubicon”, its new Git storage architecture capable of 7,200 pushes per second to one repository and 5,000 concurrent agents, built on a simple insight: only reference updates need coordination. Immutable Git objects go to Azure Blob Storage; the tiny mutable state goes to a replicated log.

← Back to the feed

Type at least two characters.

↑ ↓ navigate ↵ open esc dismiss