pickuma.
Infrastructure

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.

10 min read

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.

ToolLanguageLicenseDefault State BackendProvider Ecosystem
Terraform Best for Teams already invested in HCP Cloud and unaffected by BSL termsHCL (declarative DSL)BSL (source-available)Local / S3 / HCPLargest first-class registry
OpenTofu Best for Most teams wanting open-source IaC with a familiar HCL workflowHCL (same as Terraform)MPL 2.0 (open source)Local / S3 / cloud + state encryptionShares the provider protocol; near-parity
Pulumi Best for Teams who prefer real programming languages over a config DSLTypeScript, Python, Go, .NETApache 2.0 core; paid Pulumi CloudPulumi 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?+
For most stacks, yes. OpenTofu forked from the last MPL-licensed Terraform release and keeps the same HCL syntax, state file format, and CLI workflow, so migration is often just swapping the binary and re-initializing. Verify provider and module sourcing first, and test in a non-production workspace, but the conceptual model is identical.
Does the Terraform BSL license stop me from using it at my company?+
Almost certainly not. The BSL restriction targets companies offering a competing managed Terraform service, not teams using Terraform to manage their own infrastructure. The reasons teams moved to OpenTofu are mostly about open-source principle, governance, and where community momentum went — not a hard legal block on normal usage.
Can I use the Terraform provider ecosystem with OpenTofu and Pulumi?+
Largely, yes. Providers are separate binaries speaking a defined plugin protocol, so the major ones work with OpenTofu, which maintains its own registry. Pulumi bridges many providers from their Terraform counterparts, giving it broad coverage too, though brand-new resource types can lag behind the original Terraform provider.
How painful is importing existing infrastructure into any of these?+
Painful in all three, and this is the most underestimated adoption cost. Terraform and OpenTofu offer import blocks plus config generation, and Pulumi has pulumi import with bulk JSON specs, but at scale you face a slog of reconciling drift and hand-editing generated code. Budget real engineering time for brownfield accounts regardless of tool.
Why pick Pulumi over OpenTofu if OpenTofu is the safe default?+
Choose Pulumi when your team would rather write infrastructure in TypeScript, Python, or Go than learn HCL. Real loops, types, package managers, and unit tests are genuine leverage for developer-owned infrastructure. The tradeoff is a smaller ecosystem, the gravity of Pulumi Cloud, and a preview that executes your program rather than reading a declarative plan.

Related tools

Some links above are affiliate links. We may earn a commission if you sign up. See our disclosure for details.

Related reading

See all Infrastructure articles →

Get the best tools, weekly

One email every Friday. No spam, unsubscribe anytime.