Skip to content

Reference

Scope

Look-up facts for OpenTofu: release and support matrix, features by version, CLI flags and environment variables that differ from Terraform, state-encryption key providers and methods, backends and locking, provider protocol RPCs, security advisories, a hardening checklist, and rough performance figures. For tasks see How-to Guides. For internals see Explanation.

Release and Support Matrix

OpenTofu has no fixed release cycle. The support period of each minor series is written at the top of that series' CHANGELOG.md (RELEASE.md).

Series First GA (date) Latest patch seen (2026-09-25) Supported until Status (2026-09-25)
1.14 Not released main branch, "1.14.0 (Unreleased)" 2028-02-01 In development
1.13 Not released: v1.13.0-rc1 is out for testing (2026-09) 1.13.0-rc1 2027-08-01 Release candidate
1.12 1.12.0 (2026-05-14) 1.12.6 (2026-08-19). The branch changelog lists 1.12.7 as unreleased. 2027-02-01 Current stable
1.11 1.11.0 (2025-12-09) 1.11.14 2026-08-01 End of support
1.10 1.10.0 (2025-06) 1.10.10 TBD: not stated in the v1.10 changelog Superseded
1.9 1.9.0 (2025-01) 1.9.4 TBD Superseded
1.8 1.8.0 (2024-07-29) 1.8.11 TBD Superseded
1.7 1.7.0 (2024-04-30) TBD TBD Superseded
1.6 1.6.0 (2024-01, first GA) TBD TBD Superseded

Where these dates come from

Support dates come from the vX.Y branch changelogs. GA dates come from the OpenTofu release blog posts plus a second source: InfoQ for 1.12.0, AlternativeTo for 1.11.0, InfoQ/DEV for 1.10.0, env0/InfoQ for 1.9.0, the Linux Foundation press release for 1.7.0, and Terrateam/Spacelift for 1.8.0. The 1.12.6 date comes from the GitHub release page, as reported by newreleases.io. Rows marked TBD could not be checked because GitHub release pages are blocked from this environment.

Features by Version

Version Headline features Breaking or upgrade notes
1.6 First GA of the fork. Adds tofu test and the OpenTofu Registry (registry.opentofu.org). None. It is a drop-in replacement for Terraform 1.5.x.
1.7 State and plan encryption. Provider-defined functions. removed block. Loopable (for_each) import blocks. None noted
1.8 Early variable/locals evaluation in backend blocks, module sources and encryption config. Provider mocking and resource overrides in tofu test. .tofu override files. Removed the S3 backend's use_legacy_workflow
1.9 Provider for_each (aliased providers only). -exclude flag. encrypted_metadata_alias. tofu init prompts for early-eval variables. -show-sensitive, -consolidate-warnings and -consolidate-errors. Deprecated using ghcr.io/opentofu/opentofu as a base image
1.10 OCI registry support for providers (oci_mirror) and modules (oci://). Native S3 locking (use_lockfile). Experimental OpenTelemetry tracing. -target-file and -exclude-file. Global provider cache lock. Experimental deprecation of variables and outputs. moved across resource types. removed with lifecycle and provisioners. external key provider. New built-in functions decode_tfvars, encode_tfvars and encode_expr. -concise. Needs Linux kernel 3.2+ and macOS 11+. The pg backend changed its locking, so do not mix 1.10 with older versions on one database. The Docker image can no longer be used as a base image.
1.11 Ephemeral resources, variables and outputs and write-only attributes. lifecycle { enabled = ... } meta-argument. S3 backend object tags. Removed azurerm endpoint and msi_endpoint. SHA-1 signatures are rejected for TLS and SSH. Mocks must match provider schemas. issensitive() returns unknown for unknown values.
1.12 prevent_destroy can reference variables. lifecycle { destroy = false }. The registry serves both h1: and zh: hashes, so tofu init records every platform. -json-into=FILE. Concurrent provider downloads. import by resource identity. language block. const variables. Warnings for attributes the provider schema marks deprecated. local backend writes pretty-printed JSON. WinRM provisioner connections deprecated. OPENTOFU_USER_AGENT removed. Last series that supports macOS 12. Expect extra h1: lines in lock files.
1.13 (RC) Experimental Symbol Libraries (language { experiments = [symbol_libraries] }). Experimental -lint. convert() and assume...() functions. Windows ARM64 builds. Saved plans embed provider schemas. aws_kms gains encryption_context, gcp_kms gains AAD, and openbao gains associated_data. tofu providers lock -oci-mirror. WinRM removed. Needs macOS 13+. Last series with 32-bit (386, arm) builds. base64gzip output changes but still decompresses to the same bytes.
1.14 (dev) tofu plan groups repeated warnings into one. mock_provider gains a source argument. No official 32-bit builds

Sources: the v1.7 to v1.12 "What's new" pages (1.12, 1.11, 1.10, 1.9), and the v1.13 and main changelogs.

OpenTofu vs Terraform: Feature Differences

Feature OpenTofu Terraform
License MPL-2.0 BSL 1.1 since 1.6 (August 2023)
Steward Linux Foundation project, CNCF Sandbox since 2025-04-23 HashiCorp, an IBM company
Client-side state and plan encryption Yes, since 1.7 No. Relies on backend or HCP Terraform encryption at rest.
Variables in backend and encryption blocks (early evaluation) Yes, since 1.8 No
Variables in module source / version Yes, since 1.8 Yes, since 1.15
Provider for_each Yes, since 1.9 No
-exclude planning flag Yes, since 1.9 No
OCI registry distribution of providers and modules Yes, since 1.10 No
.tofu override files Yes, since 1.8 Not applicable
Ephemeral resources and write-only attributes Yes, since 1.11 Yes (Terraform added them first)
Public registry registry.opentofu.org, searchable at search.opentofu.org registry.terraform.io
Provider plugin protocol gRPC tfplugin5 / tfplugin6 Same, so provider binaries are shared

Terraform-only features

Features that Terraform added after the fork, and that OpenTofu has not implemented, will not work under tofu. HCP Terraform-specific workflows are one example. Check the migration guide before switching a configuration that targets Terraform 1.6 or later.

CLI Flags and Commands Specific to OpenTofu

Flag / command Applies to Since Purpose
-exclude=ADDR plan, apply 1.9 Skip the given resources. The opposite of -target.
-target-file=FILE / -exclude-file=FILE plan, apply 1.10 Read target or exclude addresses from a file, one per line, # comments allowed
-show-sensitive plan, apply, others 1.9 Show sensitive values in output
-consolidate-warnings / -consolidate-errors most commands 1.9 Group similar diagnostics
-concise plan, apply 1.10 Shorter output for automation
-json-into=FILE most commands 1.12 Write machine-readable JSON to a file while the terminal keeps human-readable output
-deprecation=module:all (or module:local, module:none) plan and other commands Documented by 1.12 (first version TBD) Choose which modules produce deprecation warnings (default module:all)
-suppress-forget-errors destroy 1.12 Exit 0 when resources are forgotten instead of destroyed
-lock=false, -lock-timeout= console 1.12 Control state locking in tofu console
-lint supported commands 1.13 (experimental) Run the built-in lint rules
tofu providers lock -oci-mirror=... providers lock 1.13 Lock hashes from an OCI mirror

Environment Variables

Variable Purpose
TF_ENCRYPTION Encryption configuration in HCL or JSON. It is merged with the code configuration, and its values win.
TF_PLUGIN_CACHE_DIR Shared provider cache. Since 1.10 it has a filesystem lock, so concurrent runs can share it.
TF_LOG, TF_LOG_PATH Debug logging. Since 1.13 it also carries OpenTelemetry library log lines.
OTEL_TRACES_EXPORTER=otlp, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_INSECURE Turn on experimental tracing (1.10+). Traces go only to the collector you configure.
BROWSER Browser used by tofu login on Unix (1.12+)
TF_VAR_<name>, TF_CLI_ARGS*, TF_DATA_DIR, TF_WORKSPACE Same meaning as in Terraform

File Names and Extensions

Terraform name OpenTofu-only override (1.8+) Notes
foo.tf foo.tofu When both exist, OpenTofu ignores foo.tf
foo.tf.json foo.tofu.json
foo_override.tf foo_override.tofu
foo.tftest.hcl foo.tofutest.hcl Test files
foo.tftest.json foo.tofutest.json
.terraform.lock.hcl Same name Provider addresses are recorded as registry.opentofu.org/...
terraform.tfstate Same name Same JSON format. Encrypted state is an envelope that Terraform cannot read.

State Encryption Reference

Configure encryption in terraform { encryption { ... } } or through TF_ENCRYPTION. Every setup has three parts: one or more key_provider blocks, a method block, and state, plan and remote_state_data_sources targets (docs).

Key providers

Key provider Since Required options Notes
pbkdf2 1.7 passphrase (at least 16 characters) or chain Defaults: key_length 32, iterations 600,000 (minimum 200,000), salt_length 32, hash_function sha512 (sha256 also allowed, sha1 not)
aws_kms 1.7 kms_key_id, key_spec (for example AES_256), plus region and credentials Authenticates like the S3 backend. encryption_context is added in 1.13.
gcp_kms 1.7 kms_encryption_key, key_length (1 to 1024) Authenticates like the GCS backend. AAD is added in 1.13.
openbao 1.7 key_name (transit key) Optional token (or BAO_TOKEN), address (or BAO_ADDR), transit_engine_path (default /transit), key_length (default 32). associated_data is added in 1.13.
azure_vault Documented in v1.12 (first version TBD) vault_uri, vault_key_name, key_length Always uses Entra ID. symmetric plus symmetric_key_size for Managed HSM.
external 1.10 (experimental) command (argv list) Runs an external program, such as a password manager CLI. Can be chained.

Every key provider also accepts encrypted_metadata_alias (1.9+). It sets a fixed metadata key, so you can rename the key provider later.

Methods

Method Notes
aes_gcm The only built-in encryption method. Needs a 16, 24 or 32-byte key. Suffers from "key saturation", so use PBKDF2 with a strong passphrase or a KMS that rotates keys.
external Experimental. An external program does the encryption.
unencrypted Explicit no-op, used only as a fallback while migrating to or from encryption

Target blocks

Block Options
state { } method, enforced = true (refuse to write plaintext), fallback { method = ... }
plan { } Same options as state
remote_state_data_sources { default { method = ... } remote_state_data_source "name" { ... } } Decrypt state read through terraform_remote_state

Compatibility guarantee

OpenTofu keeps each documented key provider and method for at least one more minor version after it is deprecated, and prints a warning on plan and apply. Do not rename key providers or methods once data is encrypted unless you set encrypted_metadata_alias or use a fallback block.

Backends and State Locking

Backend Locking Notes
local Yes (OS file locks) Default. Writes terraform.tfstate. Pretty-printed JSON since 1.12.
s3 DynamoDB table (dynamodb_table) or a native lock file (use_lockfile = true, 1.10+, uses S3 conditional writes) Both can be on at once during migration. Supports object tags (1.11+) and aws login credentials (1.12+).
gcs Yes (lock object) Google Cloud Storage
azurerm Yes (blob lease) Supports customer-provided and customer-managed keys (1.12+) and Azure DevOps workload identity federation (1.12+)
pg Yes (PostgreSQL advisory locks) Locking changed in 1.10. Custom table names since 1.10.
kubernetes Yes Stores state in a Secret
consul Yes Stores state in the Consul KV store
cos Yes Tencent Cloud Object Storage
oss Yes Alibaba Cloud OSS
http Optional (needs lock_address / unlock_address) force-unlock supported since 1.10
remote Handled by the remote service For TFE/TACOS-compatible APIs

Backends that Terraform removed in 1.3 (artifactory, etcd, etcdv3, manta, swift) are not in the OpenTofu docs either.

Dependency Lock File Hashes

Prefix What it hashes Where it comes from
zh: SHA-256 of the provider's distribution .zip archive ("zip hash") The registry's SHA256SUMS for every platform
h1: Hash of the unpacked package contents ("hash scheme 1") Computed locally, and served by the OpenTofu registry since 1.12

Since 1.12, tofu init records h1: and zh: hashes for all platforms. In most cases you no longer need tofu providers lock for cross-platform teams. The first init after upgrading adds new h1: lines. That is expected.

Provider Protocol RPCs

Providers are separate processes that speak gRPC protocol 5 (tfplugin5) or 6 (tfplugin6). Some RPCs have different names in the two versions.

RPC (v6 name / v5 name) Purpose
GetProviderSchema / GetSchema Returns provider, resource, data source, ephemeral resource and function schemas
ValidateProviderConfig / PrepareProviderConfig Validates the provider configuration and fills in defaults
ValidateResourceConfig / ValidateResourceTypeConfig Validates one resource's configuration
ConfigureProvider Passes credentials, region and other provider settings
UpgradeResourceState Migrates stored state from older schema versions
ReadResource Refreshes one resource's real-world state
PlanResourceChange Computes the proposed new state
ApplyResourceChange Creates, updates or deletes the object
ImportResourceState Imports an existing object
ReadDataSource Reads a data source
GetResourceIdentitySchemas / UpgradeResourceIdentity Resource identity, used by import { identity = ... } in 1.12+
MoveResourceState Moves state across resource types (used by moved, 1.10+)
OpenEphemeralResource / RenewEphemeralResource / CloseEphemeralResource Ephemeral resource lifecycle (1.11+)
CallFunction Provider-defined functions (1.7+)

Source: the plugin protocol docs and the tfplugin*.proto files in the same directory. The newest file in the v1.12 branch is tfplugin6.10.proto. It also defines RPCs for list resources, actions and pluggable state stores, which track Terraform's protocol. This page has not verified whether OpenTofu core calls them (TBD).

Platform Requirements

Platform Requirement
Linux Kernel 3.2+ (1.10+)
macOS 11+ (1.10 to 1.12). 13 Ventura+ (1.13+).
Windows amd64. ARM64 is officially supported from 1.13.
32-bit (386, arm) Built up to 1.13. Dropped in 1.14.
Docker ghcr.io/opentofu/opentofu:<tag>-minimal images exist only so you can copy the binary into your own image (1.10+)

Security Advisories (v1.12 Series)

Fixed in Issue
1.12.1 Hangs or panics over SSH. Revoked CA SignatureKey not checked.
1.12.2 Crafted JWE could hang or panic the OpenBao key provider (wrapping algorithms). Unescaped bytes in SSH errors. High CPU use against an attacker-controlled server.
1.12.3 Arbitrary file read during git operations through a crafted module URL
1.12.5 Go stdlib Encrypted Client Hello leaked PSK identities
1.12.6 Credentials re-sent to the target of a redirect from an OCI registry. CPU/memory exhaustion from crafted relative URLs returned by an attacker-controlled backend or registry.
1.12.7 (unreleased) A malicious SSH server could deadlock remote-exec and file provisioner connections

Source: the v1.12 CHANGELOG. Report vulnerabilities through GitHub Private Vulnerability Reporting (SECURITY.md).

Provider Credential Sources (AWS Example)

These are the usual AWS provider credential sources, roughly in the provider's precedence order.

Order Source Recommended for
1 Static credentials in the provider block Never in production
2 Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) CI/CD with short-lived credentials
3 Shared config and credentials files (~/.aws/config, ~/.aws/credentials), including SSO profiles Local development
4 Container or instance role (ECS task role, EC2 instance profile) OpenTofu running on AWS compute
n/a assume_role / assume_role_with_web_identity in the provider block (layered on any source above) Cross-account access, CI OIDC

Remote Backend Security Properties

Backend Encryption at rest In transit Locking
S3 SSE-S3, SSE-KMS, SSE-C (encrypt = true, kms_key_id) TLS DynamoDB or use_lockfile
GCS Google-managed keys or CMEK TLS Lock object
Azure Blob Microsoft-managed keys, CMK or CPK TLS Blob lease
PostgreSQL Depends on server/disk configuration TLS (configure sslmode) Advisory locks
Consul Depends on Consul configuration TLS (recommended) Session locks

Defense in depth

Backend encryption protects the storage medium. OpenTofu state encryption protects the state content from anyone who can read the bucket. Use both in production.

Security Hardening Checklist

  • Turn on state and plan encryption with a KMS-backed key provider (aws_kms, gcp_kms, azure_vault, openbao)
  • Set enforced = true in state {} and plan {} so plaintext is never written
  • Back up keys and test decryption before you encrypt production state
  • Use a remote backend with state locking for every team environment
  • Turn on backend encryption at rest (S3 SSE-KMS, GCS CMEK, and others) and bucket versioning
  • Never hardcode provider credentials in .tf files. Use OIDC or workload identity, IAM roles, or dynamic secrets.
  • Prefer ephemeral resources and write-only attributes (1.11+) for secrets so they never reach state
  • Commit .terraform.lock.hcl to version control
  • Mark sensitive variables and outputs with sensitive = true
  • Limit local state file permissions to the owner (chmod 600)
  • Pin module sources to versions, commit SHAs or OCI digests. Modules are not signature-verified.
  • Rotate encryption keys regularly with the fallback block
  • Stay on a supported series and apply patch releases promptly. The v1.12 series had six security-relevant patches in 2026.

Performance Figures (Unsourced Estimates)

Unsourced performance data

Do not plan capacity from these numbers. They are rough estimates from vendor documentation, community reports and engineering judgment. They are not controlled benchmarks: hardware, versions and methods were not recorded. Run your own measurements. The main levers are -parallelism (default 10), provider API rate limits, and splitting state into smaller root modules.

Plan and apply time by state size

State size (resources) Plan time Apply time (parallelism=10)
50 < 5 s 30 s to 2 min
200 10 to 30 s 2 to 5 min
1,000 1 to 3 min 10 to 30 min
5,000 5 to 15 min 30 min to 2 h

Provider timings

Provider Init time Resource create Notes
AWS 2 to 5 s 5 to 30 s per resource API rate limits apply
Azure 3 to 8 s 10 to 60 s per resource Slower API responses
GCP 2 to 5 s 5 to 30 s per resource Similar to AWS
Kubernetes 1 to 3 s 1 to 5 s per resource Fast for small objects

State file scaling

Resources State file size Refresh time
100 100 KB to 1 MB 10 to 30 s
1,000 1 to 10 MB 1 to 5 min
10,000 10 to 100 MB 10 to 30 min

Rule of thumb (not an OpenTofu limit): once a state file passes tens of MB, split it, because every plan refreshes every resource. Recent releases improved the performance of large graphs (1.9), provider installation (1.10, 1.12) and long depends_on chains (1.13).

Sources