on
OpenTofu 1.10 for Terraform Users: What’s New, Why It Matters, and How to Get Started
If you’ve heard people say “OpenTofu is Terraform, but truly open,” you’re not far off. OpenTofu began as a community fork after Terraform moved to a non‑open‑source license; it’s now stewarded by the Linux Foundation and developed in the open. Think of it like swapping the needle on a record player: the music (your HCL, modules, and providers) still plays, but the ecosystem and upgrade path are now community‑governed and open. (opentofu.org)
The recent OpenTofu 1.10 release is a big deal for day‑one users and veteran Terraform hands alike. It adds practical capabilities like distributing providers/modules via OCI registries, native S3 state locking without DynamoDB, and opt‑in OpenTelemetry tracing—quality‑of‑life changes you’ll feel immediately in real pipelines. (opentofu.org)
Below is a concise, hands‑on intro to OpenTofu with enough context to confidently try it on a small project or start planning a migration.
The one‑minute backstory
- In August 2023, Terraform’s license changed from MPLv2 to the Business Source License (BSL), which isn’t OSI‑approved open source. In response, the community forked the last MPLv2 version and formed OpenTofu under the Linux Foundation to keep an open, neutral, and backward‑compatible path. (opentofu.org)
- OpenTofu has since matured via stable releases (1.7, 1.8, 1.9, 1.10), with the 1.10 milestone emphasizing distribution, security, and CI safety. (opentofu.org)
What’s new in 1.10 that you’ll feel on day one
Here are the headline features through a newcomer’s lens:
- OCI registry support for providers and modules
- You can mirror providers into your own container registry (great for air‑gapped or compliance‑heavy shops) and pull modules directly with an oci:// source. This decouples you from public endpoints during deploys. (opentofu.org)
- Native S3 state locking (no DynamoDB required)
- Flip a single setting and S3 can handle state locks using conditional writes. Fewer moving parts, simpler ops. (opentofu.org)
- Target/exclude files
- Keep resource target/exclude lists in version control for safer, repeatable partial applies in CI. (opentofu.org)
- Global provider cache lock
- Concurrency‑safe provider cache for parallel CI jobs—goodbye cache corruption. (opentofu.org)
- OpenTelemetry tracing (experimental, opt‑in)
- Local‑only tracing to help debug slowness; nothing is sent anywhere unless you configure it. (opentofu.org)
- Deprecation attributes (experimental)
- Module authors can mark variables/outputs as deprecated with helpful messages, easing upgrades across teams. (opentofu.org)
Bonus from 1.9 you might have missed: provider for_each, which lets you dynamically spin up per‑region provider instances for multi‑region builds with less boilerplate. (opentofu.org)
Compatibility snapshot: “Will my code work?”
- Language parity: You still write HCL, still use a terraform {} block, and your resources/modules look the same.
- Registry and providers: OpenTofu uses a public registry (registry.opentofu.org) with providers/modules you browse at search.opentofu.org. Provider addressing defaults to that host unless you specify another. Integrity is enforced with checksums and signatures. (opentofu.org)
Quickstart: a tiny OpenTofu project that shows the new stuff
Below we’ll combine four ideas you’ll likely use early: S3 backend with native locking, state encryption, provider iteration across regions, and a minimal resource.
1) Backend with native S3 locking
- This keeps the state in S3 and uses a lockfile alongside it; no DynamoDB table needed.
terraform {
backend "s3" {
bucket = "my-tofu-state"
key = "prod/global.tfstate"
region = "us-east-1"
use_lockfile = true // native S3 locking
}
}
This relies on S3’s conditional writes to lock state safely. Check your S3‑compatible provider supports this behavior. (opentofu.org)
2) Enable state encryption at rest (end‑to‑end)
- OpenTofu can encrypt state and plan files regardless of backend. Here’s a simple passphrase‑based setup using PBKDF2 + AES‑GCM:
variable "state_passphrase" {
description = "Strong passphrase used to derive encryption keys"
type = string
sensitive = true
}
terraform {
encryption {
// Derive keys from a passphrase via PBKDF2
key_provider "pbkdf2" "kdf" {
passphrase = var.state_passphrase
}
// AES-GCM encryption method
method "aes_gcm" "m1" {
keys = key_provider.pbkdf2.kdf
}
// Apply to state; you can also configure plan {} similarly
state {
method = method.aes_gcm.m1
enforced = true
}
}
}
OpenTofu added end‑to‑end state encryption in 1.7 and documents usage and operational caveats (e.g., key rotation). If you’re migrating an existing unencrypted state, use a fallback path during the first apply to re‑write state securely. (opentofu.org)
3) Provider iteration for multiple regions
- Define one aliased provider that expands per region with for_each, then bind resources to the right instance:
variable "aws_regions" {
description = "Map of regions to region-specific settings"
type = map(object({
vpc_cidr_block = string
}))
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
provider "aws" {
alias = "by_region"
for_each = var.aws_regions
region = each.key
}
resource "aws_vpc" "private" {
for_each = { for r, cfg in var.aws_regions : r => cfg if cfg != null }
provider = aws.by_region[each.key]
cidr_block = each.value.vpc_cidr_block
}
The docs cover the rules: use alias with for_each; select the provider instance in your resources; keep provider instances around long enough to destroy resources cleanly. (opentofu.org)
4) Optional: set an OCI mirror for providers
- If you run in an air‑gapped network or want tighter control, point the CLI to your registry:
# ~/.opentofu.d/config.tfrc
provider_installation {
oci_mirror {
repository_template = "registry.example.com/opentofu-providers/${namespace}/${type}"
include = ["registry.opentofu.org/*/*"]
}
}
From then on, tofu init pulls providers from your mirror. You can also reference modules via oci:// sources directly. (opentofu.org)
Migrating from Terraform: a safe, short path
If you’re currently on Terraform, OpenTofu’s migration docs recommend a stepped approach that reduces surprises:
- Always start from “no pending changes.” Run plan/apply in Terraform first so you’re switching a steady state. Back up your state. (opentofu.org)
- Match versions on the bridge:
- From Terraform 1.6.x: first move to OpenTofu 1.6.2, complete a no‑change apply to refresh state, then upgrade to the latest OpenTofu. (opentofu.org)
- From Terraform 1.9.x: move to OpenTofu 1.9.0 first, then upgrade to latest. The docs call out minor adjustments and compatibility notes. (opentofu.org)
- After the bridge version, upgrade to 1.10 and use the “What’s new” notes to validate anything that changed in your environment (e.g., PostgreSQL backend locking behavior). (opentofu.org)
A good pilot migration is a small workspace (or a dev environment) with a familiar provider. Once you’re happy, roll the approach across modules. If you’re adopting state encryption at the same time, follow the fallback steps to avoid lockouts and keep a clean rollback plan. (opentofu.org)
Working with providers and the Registry
- Finding providers/modules: the OpenTofu Registry exposes a searchable catalog at search.opentofu.org. It mirrors docs for thousands of providers and tens of thousands of modules. (opentofu.org)
- Provider addresses and defaults: provider addresses use hostname/namespace/type, defaulting to the OpenTofu registry host if omitted. For example, hashicorp/aws resolves to the public registry by default. (opentofu.org)
- Integrity and distribution: the registry tracks versions, checksums, and keys; you can also implement the registry protocol internally if you need your own origin. (opentofu.org)
Observability and CI hygiene
- Tracing: if curious where “time went” during plans/applies, enable OpenTelemetry and point it at your collector—disabled unless you opt in. Great for local debugging or CI perf hunts. (opentofu.org)
- Safer concurrency: the global provider cache lock helps parallel pipelines share a cache without corrupting it—handy when you run many tofu init steps at once. (opentofu.org)
- Target/exclude via files: store resource lists in repo, so CI steps can reliably apply only what’s needed (or exclude experiments) without hand‑typing addresses. (opentofu.org)
A few practical tips
- Keep the “terraform” block name: Yes, it still says terraform {} in OpenTofu code. That’s expected; it’s configuration for the tooling, not the brand.
- Pin providers and commit the lock file: same good practice as before; it ensures reproducible init in CI. The docs recommend constraining versions and using a shared plugin cache. (opentofu.org)
- Start with encryption in dev: turn it on early so you learn the recovery/rotation story before production. The docs outline enforcement, fallback, and key‑rollover workflows. (opentofu.org)
Why teams are picking OpenTofu
- Governance and license: OpenTofu is MPLv2 under neutral foundation governance; the community drives features via open RFCs. If you care about open composability around your infra tooling, this matters. (linuxfoundation.org)
- Velocity on long‑requested features: state encryption (1.7), provider iteration (1.9), and now OCI distribution and native S3 locking (1.10) are very practical improvements that reduce toil. (opentofu.org)
Balanced take: Terraform remains a capable tool, and many shops will run both during a measured transition. But if “remain open” and “reduce operational friction” are north stars, OpenTofu’s current momentum and community governance make it easy to trial—no grand rewrites required.
Where to go next
- Read “What’s new in 1.10” for a crisp overview and upgrade notes. (opentofu.org)
- Browse providers/modules on the Registry to confirm what you need is available. (opentofu.org)
- If you’re migrating, use the version‑specific guides (e.g., from 1.6.x or 1.9.x) and do a no‑change apply before switching. (opentofu.org)
- Set a small success criteria (e.g., one module, one region), enable native S3 locks, and—if appropriate—turn on state encryption. Then iterate.
With a low‑risk pilot, you can hear the music play in a few hours: same HCL melody, new capabilities that keep you in tune with modern CI, security, and distribution needs—without changing the songbook.