Cloud & Infrastructure · Infrastructure as Code
Terraform vs OpenTofu vs Pulumi: Picking Your IaC Tool in 2026
HashiCorp moved Terraform to a Business Source License in August 2023. OpenTofu forked it under the MPL. Pulumi took a different path entirely. Two and a half years on, the dust has settled enough to make a clear-headed choice.
Anurag Verma
7 min read
Sponsored
In August 2023, HashiCorp relicensed Terraform under the Business Source License (BSL 1.1). The change prohibited competing vendors from using Terraform in commercial products without a license from HashiCorp. Existing users were unaffected — the BSL allows free use for most purposes — but the signal was clear: Terraform was moving away from its open-source roots.
Within weeks, a coalition of companies (Gruntwork, Spacelift, env0, and others) forked Terraform 1.5.5 under the Mozilla Public License and donated the fork to the OpenTofu organization, later joined by the Linux Foundation. OpenTofu 1.6.0 shipped in January 2024.
IBM acquired HashiCorp in April 2024 for $6.4 billion. Terraform is now an IBM product.
That’s the background. Here’s how teams should think about the decision today.
The Three Options
Terraform (HashiCorp/IBM)
Terraform remains the most widely deployed IaC tool. It has the largest provider ecosystem (over 4,000 providers on the Terraform Registry), the most third-party tooling (Terragrunt, Atlantis, Spacelift, env0), and the deepest institutional knowledge in the industry. The HCL configuration language is well-understood and has significant tooling support.
The BSL restriction targets vendors, not users. If you’re using Terraform to manage your own infrastructure, the license change has no practical effect. You can continue using it, the registry is still public, and your existing configurations work fine.
The open question for Terraform is direction. IBM has stated they’ll continue investing in it, but the pace of open development has slowed since the relicensing. The 1.9 and 1.10 releases added ephemeral resources, module testing improvements, and some stack previews — useful but not transformative.
OpenTofu
OpenTofu is a drop-in replacement for Terraform 1.5.x and later. The HCL syntax is the same. Existing Terraform modules work without modification. The state file format is compatible. Switching from Terraform to OpenTofu is typically a one-line change in your CI pipeline: replace terraform with tofu.
OpenTofu 1.7 and 1.8 added features that diverge from Terraform: provider-defined functions, early evaluation of variables, and a loophole-free implementation of for_each in module definitions that Terraform’s implementation still gets wrong in edge cases. These are genuine improvements, not just parity.
The project is backed by Gruntwork, Spacelift, Harness, Scalr, and others with clear commercial interest in keeping it healthy. The governance structure is a technical steering committee — similar to the model that kept Linux kernel development independent of any single vendor.
Pulumi
Pulumi is architecturally different from both. Instead of HCL, you write infrastructure in TypeScript, Python, Go, C#, or Java. Your infrastructure code is real code, in a real programming language, with all the abstractions that implies.
// Pulumi TypeScript example
import * as aws from "@pulumi/aws";
const bucket = new aws.s3.Bucket("my-bucket", {
acl: "private",
tags: { Environment: "production" },
});
const policy = new aws.s3.BucketPolicy("bucket-policy", {
bucket: bucket.id,
policy: bucket.id.apply(id => JSON.stringify({
Statement: [{
Effect: "Allow",
Principal: { Service: "lambda.amazonaws.com" },
Action: "s3:GetObject",
Resource: `arn:aws:s3:::${id}/*`,
}],
})),
});
export const bucketName = bucket.id;
For teams already writing Python or TypeScript for their application code, Pulumi removes the mental overhead of learning HCL. You get real loops, real conditionals, real functions, real type checking, and real dependency management. You can write unit tests for your infrastructure with standard test frameworks.
The tradeoff: the provider ecosystem is smaller than Terraform’s, though Pulumi’s conversion layer lets you use Terraform providers through a compatibility shim. The mental model of Pulumi’s execution engine is also different and takes time to internalize.
Pulumi is fully open-source (Apache 2.0). The company monetizes through Pulumi Cloud (state management, secrets, CI/CD integration). The self-hosted state backend works with S3, Azure Blob, or GCS if you don’t want the managed service.
Comparing the Three
| Terraform | OpenTofu | Pulumi | |
|---|---|---|---|
| Language | HCL | HCL | TypeScript, Python, Go, C#, Java |
| License | BSL 1.1 | MPL 2.0 | Apache 2.0 |
| State management | Local / S3 / Terraform Cloud | Local / S3 / OpenTofu Cloud | Local / S3 / Pulumi Cloud |
| Provider ecosystem | 4,000+ | Same (compatible) | ~130 native + Terraform shim |
| Testing support | Terraform Test (HCL) | OpenTofu Test | Standard language test frameworks |
| Current active version | 1.10.x | 1.9.x | 3.x |
| Governance | HashiCorp/IBM | Linux Foundation | Pulumi Corp |
| Atlantis / Spacelift | Full support | Full support | Pulumi support (less common) |
The Migration Question
If you’re currently on Terraform, the question is whether to migrate and if so, to what.
Staying on Terraform is defensible for most teams. The license change doesn’t affect internal use. If your organization has significant HCL expertise and a large Terraform codebase, the switching cost to either OpenTofu or Pulumi is real. IBM has financial incentive to keep Terraform working — it’s now an enterprise product with paying customers.
Migrating to OpenTofu is low risk and low cost. It’s the same language, the same provider ecosystem, and the same workflow. The migration is a toolchain swap, not a rewrite. Teams concerned about the BSL or IBM’s long-term stewardship can move with minimal friction. For greenfield projects, OpenTofu is an easy default — you get OSS licensing without giving up anything you’d get from Terraform.
Migrating to Pulumi is a bigger bet with a bigger payoff for the right team. If your infrastructure team writes application code daily, Pulumi’s model will feel natural. For teams that find HCL limiting — complex conditional logic, dynamic resource generation, shared abstractions across projects — Pulumi’s general-purpose language model is genuinely better for those use cases. The migration is a rewrite of your configuration, not a drop-in swap.
The cases where Pulumi wins clearly:
- Infrastructure that requires complex logic (dynamic resource counts, conditional module composition)
- Teams that want to unit-test infrastructure code
- Organizations already using TypeScript or Python everywhere and willing to bet on unified tooling
The cases where Terraform or OpenTofu wins clearly:
- Large existing HCL codebases
- Teams primarily in operations roles who don’t write application code daily
- Projects that depend heavily on the Terraform module registry or third-party Terraform modules
Practical Setup: OpenTofu Migration
For a team moving from Terraform to OpenTofu:
# Install tofu (Linux)
snap install opentofu --classic
# or via brew on macOS
brew install opentofu
# Verify
tofu version
In your CI pipeline, replace the Terraform setup action:
# Before
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.0"
- run: terraform init && terraform plan
# After
- uses: opentofu/setup-opentofu@v1
with:
tofu_version: "1.9.0"
- run: tofu init && tofu plan
Your .tf files and terraform.tfstate files work unchanged. The provider plugins will be re-downloaded from the OpenTofu registry (which mirrors the Terraform registry for community providers).
State Backend Considerations
One often-overlooked migration concern: Terraform Cloud and HCP Terraform (HashiCorp’s hosted state service) are BSL-licensed and not available to OpenTofu users without agreeing to HashiCorp terms. OpenTofu Cloud (hosted by the OpenTofu project) is in development but not fully production-ready as of early 2026.
For OpenTofu users, the standard approach is to use an S3-compatible backend for state:
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
This works with AWS S3, Cloudflare R2, MinIO, and any S3-compatible storage. DynamoDB (or its equivalent) provides state locking to prevent concurrent runs from corrupting state.
The Decision Framework
New project, no existing IaC:
- Team writes TypeScript/Python daily → Pulumi
- Team prefers declarative config or has ops-focused members → OpenTofu
Existing Terraform codebase:
- License or governance concern → OpenTofu (low migration cost)
- No license concern, happy with tooling → Stay on Terraform
- Significant pain with HCL’s limitations and willing to invest in migration → Pulumi
The decision isn’t permanent — all three tools can manage the same cloud resources, and state can be migrated between tools (with effort). But picking a clear primary and standardizing on it is worth more than hedging across all three.
Sponsored
More from this category
More from Cloud & Infrastructure
GitHub Actions in 2026: Faster Pipelines, Smaller Bills
Valkey in 2026: What Happened When Redis Changed Its License
Caching LLM Responses: When It Helps, When It Hurts, and How to Implement It
Sponsored
The dispatch
Working notes from
the studio.
A short letter twice a month — what we shipped, what broke, and the AI tools earning their keep.
Discussion
Join the conversation.
Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.
Sponsored