OpenTofu

OpenTofu 1.12.0: Safer Environments, Faster Init, Less Toil

opentofu 1 12

OpenTofu has come a long way since its inception. What started as a community fork has grown into an enterprise-grade infrastructure as code (IaC) tool that is genuinely innovating, shipping features that practitioners have been requesting for years, and pushing the boundaries of what open-source IaC looks like.

As a founding member of the OpenTofu project, we at Spacelift are proud to see that momentum reflected in our own platform: over 50% of all Spacelift runs are now OpenTofu runs. That number keeps climbing (over the last 30 days, 58% of all Spacelift Terraform stack runs are OpenTofu runs), and releases like 1.12.0 show exactly why.

OpenTofu 1.12.0 landed on May 14, and it continues OpenTofu’s history of building features that address real, recurring pain points that teams hit in their day-to-day workflows. Here’s what we think matters most.

Refactoring stacks without the risk

Anyone who has reorganized a Terraform or OpenTofu codebase knows the dread that comes with it. You want to move a resource from one state file to another, maybe because you’re breaking a large stack into smaller, team-owned pieces. But removing a resource from the configuration has always meant OpenTofu would try to destroy the actual infrastructure behind it.

The standard workaround was a careful sequence of state rm followed by import in the new location, with a window in between where the resource existed in neither state and you just had to trust that nothing would go wrong.

The new destroy = false lifecycle option changes that equation. It tells OpenTofu to drop an object from state without issuing a destroy API call, so the real infrastructure stays exactly where it is.

For teams in Spacelift managing multiple stacks, this turns the “break apart the monolith” refactor from a high-risk operation into a routine one, because you can cleanly hand a resource from one stack to another without the underlying infrastructure ever being affected.

Environment-aware protection for production resources

Every team that manages infrastructure across dev, staging, and production has run into this: prevent_destroy is exactly what you want on your production database, but it makes development environments painful to iterate on. The setting was a hardcoded boolean baked into the module, so you either had protection everywhere or nowhere.

Teams worked around it by maintaining separate module copies per environment, temporarily commenting out lifecycle blocks, or just living with the risk that someone would accidentally destroy something they shouldn’t have.

OpenTofu 1.12.0 lets you tie prevent_destroy to an input variable within the same module. Set it to true by default, override it to false in your dev environment, and the same module does the right thing in both places.

For anyone managing OpenTofu in Spacelift, the per-stack variable configuration means you define the safety behavior once per environment and it stays consistent across every run.

This is one of the first lifecycle arguments the OpenTofu team has made dynamic, and they’ve signaled that create_before_destroy and ignore_changes are next on the list in issue #1329.

Faster init phase

This one is straightforward: OpenTofu 1.12.0 fetches providers in parallel during tofu init. If your stacks only use a couple of providers, you probably won’t notice the difference. But for larger organizations pulling in 10 or 20 providers across multi-cloud configurations, init times drop meaningfully.

In Spacelift, where init runs on every plan and apply, those saved seconds compound across every run throughout the day.

Complete lock files on the first init

The dependency lock file has been a quiet source of frustration for a long time. It exists to guarantee that everyone on your team, and every CI runner in your pipeline, uses the exact same provider binaries. But tofu init previously only recorded one checksum format, which meant the lock file was incomplete the moment it was created.

Teams that used provider caches or ran internal mirrors would hit verification failures that had nothing to do with their code, and the fix was a separate tofu providers lock command that most people only discovered after losing time to a confusing error message.

The cross-platform pain was especially common. A developer committing from macOS would produce a lock file that was missing the hashes CI needed on Linux, and the other way around. Debugging it always led to the same answer: run an extra command nobody had memorized, commit the result, and move on until it happened again.

OpenTofu 1.12.0 populates both zh: and h1: hashes for every supported platform on the first init, automatically.

For Spacelift users, this means the lock file your developers commit from their local machines already contains the right checksums for Spacelift’s worker environment, with no extra steps required.

Machine-readable and human-readable output running in parallel

Platform teams building internal tooling on top of OpenTofu have always had to make an awkward tradeoff with the -json flag. It produces structured output that’s useful for automation, audit logs, and custom UIs, but turning it on means the normal terminal output disappears entirely.

If you wanted to build a progress tracker or a notification system that consumed structured plan output, you had to either give up the terminal experience or run the command twice.

OpenTofu 1.12.0 introduces -json-into=FILENAME, which writes the structured JSON stream to a separate file while the terminal continues to show the standard human-friendly output. For streaming commands like plan and apply, you can point it at a named pipe and process events as they happen. The two output streams run side by side without interfering with each other.

This probably won’t change much for individual practitioners right away, but for platform teams it opens up a category of integrations that used to require significant workarounds: real-time progress indicators, plan-diff notifications piped to Slack, cost estimate summaries extracted from the JSON stream, or audit trails captured without disrupting the developer workflow.

Two deprecations to plan for

WinRM provisioners. OpenTofu 1.12.0 warns on type = "winrm" connections, and full removal is planned for version 1.13. If your stacks rely on WinRM, now is the time to start planning a migration to OpenSSH for Windows.

32-bit architectures. Official builds for 32-bit CPUs (386 and arm) will start producing warnings in version 1.13, with removal coming in a future release. 64-bit architectures are unaffected.

Try it today

OpenTofu 1.12.0 is available from the OpenTofu GitHub releases page and through standard package managers. In Spacelift, update your stack’s OpenTofu version to 1.12.0 and your next triggered run picks up the new binary.

The OpenTofu team is building for a community that believes infrastructure tooling should be open, collaborative, and free from vendor lock-in. With version 1.12, it’s clear that open-source infrastructure as code isn’t just keeping up with modern development; it’s leading the charge. If you’re running IaC at enterprise scale or just exploring your options, OpenTofu gives you a flexible, open path forward with no strings attached.

On top of that foundation, Spacelift gives OpenTofu users a production-ready platform with policy enforcement, self-service workflows, cross-stack dependencies, and native cloud provider integrations baked in.

OpenTofu Commercial Support

Spacelift offers native and commercial support to ensure your OpenTofu success. If you need a reliable partner to run your critical workloads with OpenTofu, accelerate your migration, provide support coverage, or train your team – we are here to help.

Learn more

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide