Skip to content
Cloud Native Pulse
Release v1.13.0 1 October 2026 · 7 min read

The Release That Makes Your Plans Stop Saying (known after apply)

OpenTofu · release

OpenTofu logo

OpenTofu v1.13.0 is here, and it is on a mission to kill the most annoying three words in infrastructure-as-code: (known after apply).

Quick background, because everyone deserves a painless intro: OpenTofu is the open-source, community-driven fork of Terraform. It is a tool for infrastructure-as-code — you describe your servers, databases, networks, and cloud resources in text files, and the tool creates, changes, and destroys them for you, predictably and repeatably.

What pain does it solve? The old way of managing infrastructure was clicking around cloud consoles at 2 a.m., praying nobody remembered the magic settings from last time. OpenTofu turns that chaos into reviewable, versioned code. Your entire infrastructure becomes a pull request.

Who uses it? Platform engineers, SREs, and DevOps folks — basically anyone who provisions cloud resources and wants to sleep at night. If your team runs more than three servers, this tool is probably already in your pipeline.

So why should you care about v1.13.0 specifically? Two reasons. First, it ships a brand-new family of plan-time hint functions (convert and the assume... family) that let module authors eliminate entire categories of (known after apply) mysteries.

Second, it opens the door on two experimental bets — built-in linting and Symbol Libraries — that the Terraform lineage has not offered in this form.

Released on September 30, 2026 (the announcement post is dated a day earlier — time zones are a menace), this is deliberately a lighter release — the team shortened the cycle to align with the Go release calendar and maximize security-support time (the v1.13 series is supported until August 2027). But “lighter” still packs plenty worth reading about.

Think of it like this: OpenTofu planning is a weather forecast, and unknown values are the forecast saying “rain: maybe, who knows.” v1.13.0 lets you hand the forecaster your barometer.

What’s New in OpenTofu v1.13.0

Fewer Plan-Time Unknowns: The convert and assume Functions

Here is the classic annoyance. During a tofu plan, OpenTofu predicts what will happen if you apply your changes. But some values — like the ID of a cloud resource that does not exist yet — simply cannot be known in advance. Those show up as (known after apply).

The problem: features like count, for_each, and enabled choke on unknowns, and policy-checking software that reads machine-readable plan output is effectively blinded by them.

v1.13.0’s answer is a set of functions that let module authors give OpenTofu hints about things they know to be true but OpenTofu cannot infer on its own — a way to make more values known at plan time. Unhinted values still show as (known after apply), but whole categories of mysteries disappear.

The new convert function tells OpenTofu what type of result to expect. Feed it an unknown JSON blob, and downstream expressions can still rely on the shape:

code
output "example" {
  value = convert(jsondecode(something_dynamic.example.output_json), object({
    id   = string
    tags = map(string)
  }))
}

The assume… family goes further and hints about the value itself — for example, that an AWS VPC ID will definitely not be null and will definitely start with vpc-:

code
output "vpc_id" {
  value = assumenotnull(
    assumestringprefix(
      aws_vpc.example.id,
      "vpc-",
    )
  )
}

Now any comparison of that output against null or "" produces a known false instead of an unknown boolean — and module validation that requires the vpc- prefix runs during plan instead of apply, so you catch mistakes sooner. One honest catch, straight from the docs: if your hint turns out to be wrong, the assume call fails during apply. Only promise what the provider or vendor API guarantees. Shipped in PR #4449.

Built-in Linting (Experimental)

Ever wished your IaC tool itself would nag you about sketchy patterns, instead of waiting for a code review or — worse — an incident? v1.13.0 plants the first seed of built-in linting: run supported commands with the -lint flag and OpenTofu will check your configuration against a set of linting rules and print warning diagnostics when something smells off.

code
tofu validate -lint

This is explicitly a first iteration — internal infrastructure, rule selection, and a few initial built-in rules as examples, with the agreed commands being validate, plan, and apply. The grand plan folds related needs like policy enforcement into one comprehensive feature in future releases. The linting experiment landed via the RFC tracker in issue #4310, with the RFC itself in PR #3999.

Translation: today it warns you about your questionable life choices in HCL. Tomorrow it might refuse to let you apply them.

Symbol Libraries (Experimental)

Here is the boldest bet in this release. OpenTofu’s only unit of reuse has always been the module — but modules are designed for sharing collections of stateful resources, not for sharing plain data and logic. So teams keep copy-pasting the same helper hacks across repos like it’s 2014.

A Symbol Library is a new kind of artifact: a reusable collection of values, functions, and type aliases, importable from all the same source types modules already support (registries, git, you name it). Imagine one library defining your organization’s DNS record conventions, imported by every module so they all speak the same language:

code
typedef "recordset" {
  type = set({
    name    = string
    type    = string
    ttl     = number
    records = set(string)
  })
}

function "a_records" {
  type = symbols::dns_recordset()

  parameter "records" {
    type = map(set(string))
  }

  parameter "ttl" {
    type = number
  }

  return = [
    for name, ip_addrs in param.records : {
      name    = name
      type    = "A"
      ttl     = param.ttl
      records = ip_addrs
    }
  ]
}

The syntax is a starting point expected to evolve, the feature is experimental and subject to change — do not build production on it yet — but it is a genuinely new artifact class for OpenTofu. To try it, enable the experiment by adding it to the experiments list in the language block. Read the design in PR #4052.

Windows on ARM64, Officially

The fastest-growing corner of the Windows world just got first-class treatment: OpenTofu now publishes official packages for Windows on ARM64 (also known as aarch64) — the silicon inside newer Surface devices and the ARM servers quietly multiplying in datacenters. It took a while because the team needed CI infrastructure and provider plugin support to catch up first. Fair warning: third-party providers set their own platform policies, so you may need a newer provider version. Delivered in PR #4450.

code
tofu_1.13.0_windows_arm64.zip

Upgrade Notes: Read This Before You Upgrade

This release also removes and changes some things. None of them are zero-day fire drills, but a few will show up in your plans uninvited:

  • base64gzip output changed. A new, more efficient DEFLATE implementation produces results that are equivalent but not byte-for-byte identical. If you feed base64gzip into a resource argument, expect OpenTofu to propose updates or replacements after upgrading. The docs suggest ignore_changes as a temporary bridge if you cannot accept the new value yet. Changelog
  • WinRM provisioner support is gone. Deprecated in v1.12, removed in v1.13 — the underlying Go libraries are unmaintained. Configs with connection { type = "winrm" } will now fail with an error. Migrate to OpenSSH for Windows before upgrading. PR #4012
  • macOS 13 Ventura or later is required. The official binaries may crash or behave incorrectly on earlier versions. Changelog
  • Last call for 32-bit. v1.13 is the final release series with official 32-bit builds; tofu init on 32-bit now warns about it. Third parties may keep publishing their own builds, but official support ends with this series — plan your move to 64-bit. Issue #4018
  • Stricter SSH parsers. The SSH client used by remote provisioners now rejects some invalid input it previously accepted, to better match other implementations. If a provisioner suddenly refuses a connection, this is why. Changelog

Fixes and Improvements Worth a Nod

Eighteen bug fixes shipped — we counted — plus a stack of quieter enhancements. A few standouts:

  • Crash safety: OpenTofu now writes an errored.tfstate partial state file on a Go runtime panic — a real lifeline when recovering from a hard crash. PR #4064
  • Self-contained plan files: saved plans now embed the provider schemas needed to render them, so tofu show no longer needs to launch providers where possible. PR #4490
  • Security-adjacent: connection.script_path is now escaped correctly, no longer allowing extra commands to sneak onto the remote host alongside your script path. PR #4330
  • Plan correctness: fixed the invalid change action ForgetThenCreate error when planning replacements of resources with lifecycle { destroy = false }. Issue #4324
  • Function panics: cidrhost and templatestring no longer panic on exotic inputs (64-bit-plus host numbers; wholly sensitive vars). PR #4056, Issue #4430

Plan faster, hint honestly, and lint like someone is watching — because now, something is.

Learn More

Also on the podcast 1 · Cloud Native Pulse: Episode 1 ▶ Play 00:17:01