Terraform vs Pulumi vs OpenTofu: The IaC War in 2026
on Devops, Terraform, Pulumi, Opentofu, Iac, Infrastructure, Cloud
The IaC Landscape Has Shifted
When HashiCorp switched Terraform from MPL to the Business Source License (BSL) in August 2023, it sent shockwaves through the DevOps community. Fast forward to 2026, and the Infrastructure-as-Code (IaC) ecosystem looks dramatically different.
Three major players dominate:
- Terraform (HashiCorp/IBM) — still the market leader, but losing momentum
- OpenTofu — the open-source fork with growing enterprise adoption
- Pulumi — the code-first alternative that’s winning over developers
This post gives you the real-world comparison you need to make the right choice.
Photo by Taylor Vick on Unsplash
What Changed: The BSL Controversy
HashiCorp’s Move (August 2023)
HashiCorp changed Terraform’s license from Mozilla Public License 2.0 to Business Source License 1.1. The key restriction:
“You may not use the software if the product competes with HashiCorp’s commercial products.”
This affected:
- Cloud providers building Terraform-compatible services
- Open-source tools that wrapped Terraform
- Any company “competing” with Terraform Cloud/HCP
OpenTofu Fork (October 2023)
The Linux Foundation-backed OpenTofu forked Terraform at v1.5 before the BSL change. By 2026:
- OpenTofu 1.9 released with features Terraform hasn’t implemented
- 1,800+ contributors
- Adopted by CNCF as a sandbox project
- CNCF’s official recommendation for new cloud-native IaC projects
IBM Acquisition (2024)
IBM acquired HashiCorp for $6.4B. The DevOps community held its breath. So far:
- Terraform continues development
- Terraform Cloud rebranded to HCP Terraform
- Enterprise pricing increased ~30%
- Some enterprise customers quietly migrating to OpenTofu
Feature Comparison 2026
Core Language
Terraform (HCL)
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
Environment = var.environment
}
}
output "instance_ip" {
value = aws_instance.web.public_ip
}
OpenTofu (HCL — identical to Terraform)
# Same syntax! Compatible with Terraform modules
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
Environment = var.environment
}
}
Pulumi (TypeScript)
import * as aws from "@pulumi/aws";
const web = new aws.ec2.Instance("web", {
ami: "ami-0c55b159cbfafe1f0",
instanceType: aws.ec2.InstanceType.T3_Micro,
tags: {
Name: "WebServer",
Environment: pulumi.getStack(),
},
});
export const instanceIp = web.publicIp;
Pulumi (Python)
import pulumi
import pulumi_aws as aws
web = aws.ec2.Instance("web",
ami="ami-0c55b159cbfafe1f0",
instance_type=aws.ec2.InstanceType.T3_MICRO,
tags={
"Name": "WebServer",
"Environment": pulumi.get_stack(),
}
)
pulumi.export("instance_ip", web.public_ip)
OpenTofu-Exclusive Features (2026)
OpenTofu has moved beyond Terraform compatibility with features HashiCorp hasn’t shipped:
1. State Encryption (OpenTofu 1.7+)
terraform {
encryption {
key_provider "pbkdf2" "main" {
passphrase = var.state_passphrase
}
method "aes_gcm" "default" {
keys = key_provider.pbkdf2.main
}
state {
method = method.aes_gcm.default
}
plan {
method = method.aes_gcm.default
}
}
}
State files can contain secrets. OpenTofu encrypts them at rest — a feature the community has requested from Terraform for years.
2. Provider Iteration (OpenTofu 1.8+)
# Deploy to multiple regions with a single resource block
provider "aws" {
for_each = toset(["us-east-1", "eu-west-1", "ap-northeast-1"])
alias = each.key
region = each.key
}
resource "aws_s3_bucket" "backup" {
for_each = provider.aws
provider = each.value
bucket = "my-backup-${each.key}"
}
This eliminates the need for duplicated provider configurations.
3. Functions in Module Calls (OpenTofu 1.9+)
module "network" {
source = "./modules/network"
# Call functions directly in module arguments
cidr_block = cidrsubnet(var.vpc_cidr, 8, 0)
availability_zones = slice(data.aws_availability_zones.available.names, 0, 3)
}
Pulumi’s Unique Strengths
Full Programming Language Power
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";
const config = new pulumi.Config();
const environment = config.require("environment");
// Conditional resources — try doing THIS in HCL
const instances = environment === "production"
? createProductionCluster()
: createDevelopmentSingle();
async function createProductionCluster() {
// Fetch from external API, apply business logic
const instanceTypes = await fetchOptimalInstanceTypes();
return instanceTypes.map((type, i) =>
new aws.ec2.Instance(`web-${i}`, {
instanceType: type,
ami: getLatestAmi(type),
})
);
}
Testing (A Real Differentiator)
Pulumi supports unit testing natively — something HCL-based tools still struggle with:
import * as aws from "@pulumi/aws";
import { describe, it, expect } from "vitest";
import * as pulumi from "@pulumi/pulumi";
// Mock Pulumi resources for testing
pulumi.runtime.setMocks({
newResource: (args) => ({ id: `${args.name}-id`, state: args.inputs }),
call: (args) => args,
});
describe("Infrastructure Tests", () => {
it("should not create public S3 buckets", async () => {
const { infra } = await import("../index");
const bucket = await infra.logsBucket;
const acl = await bucket.acl;
expect(acl).not.toBe("public-read");
expect(acl).not.toBe("public-read-write");
});
it("production instances should be t3.large or bigger", async () => {
pulumi.runtime.setConfig("environment", "production");
const { infra } = await import("../index");
const instanceType = await infra.webServer.instanceType;
expect(["t3.large", "t3.xlarge", "m5.large"]).toContain(instanceType);
});
});
Migration: Terraform → OpenTofu
The migration is straightforward because OpenTofu is drop-in compatible:
# 1. Install OpenTofu
brew install opentofu # macOS
# or
curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh
# 2. Replace terraform with tofu (that's literally it for simple cases)
tofu init
tofu plan
tofu apply
# 3. For state migration (if using Terraform Cloud)
terraform state pull > terraform.tfstate
tofu init -backend-config="backend.hcl"
tofu state push terraform.tfstate
Breaking changes to watch for:
- Some provider behaviors differ slightly
terraformblock →tofublock for new OpenTofu features- Terraform Cloud workspaces need migration to alternative backends
Market Share & Adoption (2026)
Based on Stack Overflow Survey 2026 and GitHub stats:
| Tool | 2023 Usage | 2026 Usage | Trend |
|---|---|---|---|
| Terraform | 68% | 52% | ↓ Declining |
| OpenTofu | 0% | 28% | ↑ Rapid growth |
| Pulumi | 15% | 31% | ↑ Strong growth |
| Ansible (IaC) | 42% | 38% | → Stable |
| CDK | 12% | 19% | ↑ Growing |
Key findings:
- Terraform still dominates due to existing module ecosystem
- OpenTofu is winning new enterprise projects (especially regulated industries that can’t use BSL)
- Pulumi is winning developer-led infrastructure teams
My Recommendation for 2026
Choose OpenTofu if:
- You’re already using Terraform and want open-source with no license risk
- Your team prefers declarative HCL syntax
- You need the massive existing module ecosystem
- You work in regulated environments that require open-source licensing
Choose Pulumi if:
- Your team consists primarily of software engineers (not ops)
- You need complex conditional logic or loops
- Infrastructure testing is a priority
- You’re building reusable infrastructure SDKs
- Python/TypeScript/Go experience is higher than HCL knowledge
Choose Terraform if:
- You’re already invested in HCP Terraform/Terraform Cloud
- You need commercial support from HashiCorp/IBM
- Your team has deep Terraform expertise and the BSL isn’t a concern
The Hybrid Approach (Pragmatic)
Many companies use both:
- Pulumi for application infrastructure (VMs, containers, databases)
- OpenTofu for foundational infrastructure (networking, IAM, DNS)
Conclusion
The IaC war is real, but it’s not destructive — it’s driving innovation. OpenTofu has forced HashiCorp to accelerate Terraform development, and Pulumi’s code-first approach is pushing the entire ecosystem toward better developer experience.
In 2026, the “right” answer depends more on your team’s culture and existing skills than on technical superiority. All three are production-ready, well-supported, and capable of managing complex cloud infrastructure.
Start with OpenTofu if you want the safest migration path from Terraform. Choose Pulumi if you want the most powerful tooling for the future.
Resources
- OpenTofu Official Docs
- Pulumi Getting Started
- OpenTofu State Encryption
- Pulumi Testing Guide
- Terraform to OpenTofu Migration
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)
