Pulumi vs Terraform vs OpenTofu: Infrastructure as Code in 2026
I ran Pulumi, Terraform, and OpenTofu against the same AWS and Cloudflare stacks for several weeks. Here is how the language model, state handling, provider coverage, and the BSL-versus-open-source split actually shape which one your team should pick in 2026.
For most of the last decade, “infrastructure as code” and “Terraform” were nearly synonymous. That stopped being true in 2023, when HashiCorp relicensed Terraform under the Business Source License (BSL), and the community responded by forking the last MPL-licensed version into what became OpenTofu under the Linux Foundation. Two and a half years later, the dust has settled enough to make a real decision. I spent several weeks running all three — Terraform, OpenTofu, and Pulumi — against the same set of stacks: an AWS VPC with ECS services and RDS, a Cloudflare DNS and Workers setup, and a small Kubernetes cluster. The goal was not to find a single winner but to figure out which tool fits which team, because the honest answer in 2026 is that it depends heavily on what your engineers already know and how your legal department reads a license.
The Language Model Is the First Fork in the Road
The single biggest difference between these tools is how you describe infrastructure, and it splits cleanly into two camps.
Terraform and OpenTofu both use HCL, the HashiCorp Configuration Language. HCL is declarative and purpose-built: you write blocks that describe resources, and the engine figures out the dependency graph and the order of operations. It is not a programming language, and that is deliberate. You get for_each, conditional expressions, and a library of built-in functions, but you do not get real loops, classes, or a package manager. For straightforward infrastructure this is a feature — HCL files read like configuration because they are configuration, and a new engineer can usually understand a module without knowing a programming language. The pain shows up when your logic gets genuinely complex. I have written for_each over a flattened map of nested objects to generate per-environment subnets, and the result is the kind of HCL that you write once, get working, and never want to touch again. OpenTofu is identical here by design — it is a drop-in fork, so the language, the .tf files, and the mental model are the same.
Pulumi takes the opposite bet: you describe infrastructure in a real programming language. TypeScript and Python are the most mature, with Go and .NET also well supported. A Pulumi program is an actual program — you import an AWS package, instantiate resource objects, and use ordinary language features for abstraction. Want to create a subnet per availability zone? That is a for loop and an array, not a flattened-map incantation. Want to share logic across stacks? That is a function or a class in a package you publish to npm or PyPI. For teams whose engineers are already fluent in TypeScript, this collapses the learning curve dramatically; you are writing code, not learning a config DSL. The cost is that you can also write bad infrastructure code — loops with side effects, clever abstractions nobody else understands, and the full range of mistakes that real languages enable. HCL’s constraints are also guardrails.
State Management and the Imports Problem Nobody Escapes
All three tools work the same way at the core: they track the real-world resources they manage in a state file, then diff your desired configuration against that state to compute a plan. Where they differ is where that state lives and how much friction surrounds it.
Terraform and OpenTofu use the same state format and the same backend model — you can store state in S3 with DynamoDB locking, in an Azure storage account, in Terraform Cloud / HCP, or locally. OpenTofu added one meaningful capability that vanilla Terraform did not have for a long time: client-side state encryption. State files routinely contain secrets — database passwords, generated keys, connection strings — and historically the guidance was “lock down your backend and never commit state to git.” OpenTofu’s state encryption lets you encrypt the state at rest with a key you control, which is a genuine security improvement and one of the clearer reasons a security-conscious team might prefer OpenTofu beyond the licensing question.
Pulumi stores state in Pulumi Cloud by default — a hosted backend that handles locking, history, and secrets encryption out of the box. You can self-host the state in S3, Azure Blob, or GCS instead, and many teams do, but the default path and the smoothest experience point at Pulumi Cloud. Pulumi encrypts secret values within the state automatically, which is nicer than the historical Terraform default. The tradeoff is gravity: the polished experience nudges you toward the hosted service, and the free tier has limits that a growing team will eventually hit.
Then there is the problem that no IaC tool has truly solved: importing existing infrastructure. If you have resources that were created by hand or by another tool, bringing them under management is tedious in all three. Terraform and OpenTofu support import blocks and a plan -generate-config-out flow that writes draft HCL, but at scale — say, a few hundred existing resources across an account — it remains a slog of running imports, reconciling drift, and hand-editing generated config that is rarely clean. Pulumi has pulumi import which can generate code for a resource, and bulk import via a JSON spec, but it inherits the same fundamental tedium. This is the single biggest source of pain when adopting any of these tools on a brownfield account, and you should budget real engineering time for it regardless of which one you choose. The drift that accumulates between your state and reality is a forever-tax, not a one-time migration cost.
Provider Ecosystem and Maturity
This is where Terraform’s head start still matters, and where OpenTofu inherits the advantage.
The Terraform Registry is enormous — thousands of providers covering essentially every cloud, SaaS, and on-prem system you might want to manage, plus a vast library of community modules. OpenTofu maintains its own registry, but crucially, the provider ecosystem is largely shared at the protocol level: providers are separate binaries that speak a defined plugin protocol, and the major providers (AWS, Google, Azure, Cloudflare, and so on) work with OpenTofu. OpenTofu’s registry resolves providers from a network of sources, and in my testing the providers I reached for all resolved without drama. The thing to verify is module sourcing and any provider that is published only to the official Terraform Registry under terms that restrict redistribution — check before you assume parity, but for mainstream infrastructure the coverage is effectively equivalent.
Pulumi takes a clever shortcut here: many Pulumi providers are bridged from the corresponding Terraform providers, which means Pulumi rides on the same underlying provider engineering for AWS, Azure, GCP, and others. In practice this gives Pulumi broad coverage that tracks the Terraform providers reasonably closely, though there can be a lag when a brand-new resource type lands in the Terraform provider before the bridged Pulumi version exposes it. Pulumi also has native providers for some clouds that are generated directly from the cloud’s API surface, which can mean faster coverage of new features for those specific providers. The net effect: Terraform and OpenTofu have the deepest first-class ecosystem, and Pulumi is close behind by standing on much of the same work.
Licensing: The Reason This Comparison Exists
You cannot discuss IaC in 2026 without the license, because it is the reason the landscape fractured.
Terraform is BSL-licensed. The practical meaning for the overwhelming majority of teams is: you can use it freely to manage your own infrastructure. The BSL’s restriction is aimed at companies offering a competing managed Terraform service. So if you are a normal engineering org using Terraform to run your own stacks, the BSL does not stop you. The reasons teams still moved off Terraform are softer and real: discomfort with a license that can change, the principle of running open-source tooling, and the fact that the community energy — contributions, third-party tooling, conference talks — shifted noticeably toward OpenTofu.
OpenTofu is MPL 2.0, fully open source, and governed by the Linux Foundation rather than a single vendor. For organizations with open-source mandates, government and regulated contexts, or simply a preference for community governance, this is the deciding factor. Pulumi’s core engine and SDKs are open source under Apache 2.0; the commercial layer is Pulumi Cloud, the hosted backend and team features. So both OpenTofu and Pulumi let you avoid the BSL entirely, by different routes — OpenTofu by being the open continuation of Terraform itself, Pulumi by being a different tool with an open core and a paid SaaS.
| Tool | Language | License | Default State Backend | Provider Ecosystem |
|---|---|---|---|---|
| Terraform Best for Teams already invested in HCP Cloud and unaffected by BSL terms | HCL (declarative DSL) | BSL (source-available) | Local / S3 / HCP | Largest first-class registry |
| OpenTofu Best for Most teams wanting open-source IaC with a familiar HCL workflow | HCL (same as Terraform) | MPL 2.0 (open source) | Local / S3 / cloud + state encryption | Shares the provider protocol; near-parity |
| Pulumi Best for Teams who prefer real programming languages over a config DSL | TypeScript, Python, Go, .NET | Apache 2.0 core; paid Pulumi Cloud | Pulumi Cloud (self-host optional) | Broad, largely bridged from Terraform providers |
Who Should Choose Which
After living in all three, the decision comes down to three honest questions about your team, not a feature scorecard.
Choose OpenTofu if you are starting fresh in 2026 or already run Terraform and want off the BSL with the least disruption. The migration from Terraform to OpenTofu is close to trivial for most stacks — the files, the state format, and the workflow are the same — and you gain open-source governance plus state encryption. For the majority of engineering teams, this is the path of least regret. It is what I would reach for by default.
Stay on Terraform if you are genuinely embedded in the HashiCorp ecosystem — using HCP Terraform’s run management, Sentinel policy-as-code, or the integrated workflows — and the BSL has no practical effect on your business. There is no reason to migrate purely on principle if the tooling around Terraform is delivering value and your legal team is comfortable. Switching has a cost, and “the license changed” is not by itself a reason to pay it if nothing about your usage is constrained.
Choose Pulumi if your engineers think in code and resent HCL, or if you want to share substantial logic between application and infrastructure code in the same language. Pulumi is the right call for teams where infrastructure is owned by application developers rather than a dedicated platform team, and where the leverage of real loops, types, and tests outweighs the smaller ecosystem and the pull toward Pulumi Cloud. Just go in knowing you are trading the reviewability of a declarative plan for the expressiveness of a programming language, and budget for the testing discipline that trade demands.
One thing I would not do is run a mix of all three across one organization without a strong reason. The state models, the review workflows, and the mental models differ enough that fragmenting your team’s expertise across them costs more than any single tool’s advantage is worth.
FAQ
FAQ
Is OpenTofu really a drop-in replacement for Terraform?+
Does the Terraform BSL license stop me from using it at my company?+
Can I use the Terraform provider ecosystem with OpenTofu and Pulumi?+
How painful is importing existing infrastructure into any of these?+
Why pick Pulumi over OpenTofu if OpenTofu is the safe default?+
Related tools
Beehiiv
Newsletter platform with built-in ad network and Boost referrals.
Try Beehiiv →
Webflow
Visual site builder with real CSS export and a CMS that scales.
Try Webflow →
Some links above are affiliate links. We may earn a commission if you sign up. See our disclosure for details.
Related reading
2026-06-04
Better Auth Review: The Self-Hosted, Framework-Agnostic Auth Library for 2026
A hands-on review of Better Auth, the TypeScript-first, self-hosted auth library you run against your own database — covering OAuth, 2FA, organizations, plugins, adapters, and when paying for Clerk is still the smarter call.
2026-06-04
Hetzner Cloud Review: Why Developers Are Leaving AWS for European Bare Metal
A hands-on review of Hetzner Cloud and its bare-metal servers — the price-to-performance math against AWS EC2, the dedicated vCPU lines, the server auction, and the self-hosting stack (Coolify, Dokku) that makes it work. Honest about the tradeoffs.
2026-06-04
Render Review: The Heroku Successor That Won the Indie Backend in 2026
I moved three side projects and one production API to Render over two months. Here's the honest take on git-push deploys, managed Postgres, cold starts, and where Render beats Fly.io and Railway — plus the egress and storage costs nobody mentions.
2026-06-04
Tigris vs Cloudflare R2 vs Backblaze B2: Object Storage for Edge Apps in 2026
I moved three real workloads across Tigris, Cloudflare R2, and Backblaze B2 to figure out which S3-compatible store actually fits edge apps — egress, latency, and integration compared.
2026-05-28
Caddy vs Traefik vs nginx Proxy Manager: reverse proxies for modern stacks
We migrated three production stacks across Caddy 2.8, Traefik v3.1, and nginx Proxy Manager 2.11. Here is where each one earns its keep and where it bites you.
Get the best tools, weekly
One email every Friday. No spam, unsubscribe anytime.