IaC Comparison — Terraform vs OpenTofu vs Pulumi¶
Summary
Canonical comparison of the three general-purpose IaC tools in this knowledge base: Terraform, OpenTofu and Pulumi. Terraform and OpenTofu share HCL, the state format and provider binaries but differ in license, governance and newer features. Pulumi uses general-purpose languages (plus YAML and HCL) on an Apache-2.0 engine and can run any Terraform/OpenTofu provider. Versions and facts come from the refreshed topic pages (2026-09-25).
Quick Reference¶
| Dimension | Terraform | OpenTofu | Pulumi |
|---|---|---|---|
| Latest version | 1.16.4 (2026-09-23); 1.17 in beta | 1.12.6 (2026-08-19); 1.13 in RC | 3.264.0 (2026-09-23); roughly weekly releases |
| License | BSL 1.1 since 1.6, licensor IBM (not OSI open source); 1.5.7 was the last MPL-2.0 release | MPL-2.0 | Apache-2.0 (CLI, engine, SDKs); Pulumi Cloud proprietary |
| Governance | HashiCorp, an IBM company (since 2025-02-27) | Linux Foundation project with a Technical Steering Committee; CNCF Sandbox since 2025-04-23 | Pulumi Corporation |
| Languages | HCL (or JSON) | HCL (.tf plus OpenTofu-only .tofu files) |
TypeScript/JavaScript, Python, Go, .NET, Java, YAML, HCL (Pulumi HCL, runtime: hcl) |
| Compatibility | Reference implementation | Drop-in for Terraform 1.5.x; Terraform-only features added in 1.6+ do not run | Runs Terraform/OpenTofu providers; converts or runs HCL |
| State encryption | Backend encryption at rest only; HYOK on HCP Terraform (GA 2025-09) | Native client-side state and plan encryption (1.7+) | Per-secret encryption in state via the stack's secrets provider, on Pulumi Cloud or DIY backends |
| Providers | Public registry with thousands of providers (7,335 on the registry home page, search snapshot seen 2026-09-27) | Same provider binaries; registry.opentofu.org indexes 4,603 providers (opentofu/registry metadata, counted 2026-09-27) |
Pulumi Registry (native and bridged) plus Any Terraform Provider |
| Managed platform | HCP Terraform (SaaS), Terraform Enterprise | None first-party; third-party TACOS (Spacelift, env0, Scalr, Harness) | Pulumi Cloud (SaaS or self-hosted on Enterprise) |
Feature Matrix¶
| Feature | Terraform | OpenTofu | Pulumi |
|---|---|---|---|
| Plan / preview | terraform plan |
tofu plan |
pulumi preview |
| State backends | local, s3, gcs, azurerm, oci, oss, consul, pg, http, HCP Terraform / TFE (cloud block) |
local, s3, gcs, azurerm, pg, kubernetes, consul, cos, oss, http, remote | Pulumi Cloud, S3 and S3-compatible, Azure Blob, GCS, PostgreSQL, local file |
| S3 locking without DynamoDB | use_lockfile (GA 1.11); DynamoDB arguments deprecated |
use_lockfile (1.10+) |
Lock files in DIY backends; service-side on Pulumi Cloud |
| State encryption | Backend at rest (for example SSE-KMS); HYOK on HCP Terraform | aes_gcm with key providers pbkdf2, aws_kms, gcp_kms, openbao, azure_vault, external (experimental) |
Secrets providers: Pulumi Cloud, passphrase, AWS KMS, Azure Key Vault, Google Cloud KMS, Vault Transit |
| Secrets kept out of state | Ephemeral values (1.10), write-only attributes (1.11) | Ephemeral resources and write-only attributes (1.11) | Secret outputs encrypted in state; Pulumi ESC for dynamic credentials |
| Test framework | terraform test with mocks |
tofu test (1.6+), provider mocking (1.8+) |
Language test frameworks with mocks, plus integration tests |
| Import | import blocks (1.5+), import in modules (1.16), terraform query discovery (1.14) |
import blocks, for_each import (1.7), import by resource identity (1.12) |
pulumi import (generates code) |
| Modules / components | Registry modules; variables in module source/version (1.15) |
Registry and OCI modules (1.10); variables in module sources (1.8) | Language packages (npm, PyPI, NuGet, Maven, Go modules) and multi-language components |
| Multi-instance providers | Provider aliases | Provider for_each (1.9+) |
Provider objects in code |
| Orchestration across environments | Stacks (GA 2025-09, HCP Terraform) | Workspaces and TACOS | Stacks per environment; Automation API |
| IDE support | HCL language server | HCL language server | Full language tooling (types, autocomplete, refactoring) |
| CI/CD integration | HCP Terraform / TFE runs, Atlantis, TACOS | Atlantis, Spacelift, env0, Scalr, Harness | Pulumi Deployments, Pulumi Kubernetes Operator, CI with OIDC |
| Policy as code | Sentinel and OPA on HCP Terraform / TFE; Terraform Policy CLI (-policies, GA in 1.17, currently beta) |
OPA/Conftest on plan JSON, or TACOS policy engines | Policy packs (formerly CrossGuard); org-wide enforcement in Pulumi Cloud |
| AI integration | Terraform MCP server (GA 2026) for registry and HCP Terraform/TFE workspaces | OpenTofu MCP server for registry search | Pulumi Neo agent (Pulumi Cloud) across CLI, console, PRs and MCP |
| Programmatic API | None built in (drive the CLI, JSON plan output) | None built in (drive the CLI, JSON plan output) | Automation API |
Pricing is part of the choice
HCP Terraform bills per managed resource above its free tier (Free up to 500 managed resources; Essentials, Standard and Premium from $0.10, $0.47 and $0.99 per resource per month). Pulumi Cloud editions start at $40/month (Essentials) with resource allowances per edition. OpenTofu has no first-party SaaS; TACOS vendors price separately. Details: Terraform reference and Pulumi reference.
Migration Compatibility¶
| From → To | Terraform → OpenTofu | Terraform → Pulumi | OpenTofu → Pulumi |
|---|---|---|---|
| Config | Unchanged for Terraform 1.5.x; review configs that use Terraform-only features added in 1.6+ | pulumi convert --from terraform (rewrite), or run the .tf files as Pulumi HCL (CLI 3.256.0+) |
Same as Terraform → Pulumi |
| State | Same format; tofu init and tofu plan should show no changes when coming from 1.5.x |
Adopt resources with pulumi import |
Adopt resources with pulumi import |
| Providers | Same binaries | Pre-bridged packages or pulumi package add terraform-provider |
Same |
| Effort (qualitative) | Low for 1.5.x; higher the more Terraform 1.6+ features are used | Medium to high (new language, state adoption) | Medium to high |
One-way doors
Moving back from OpenTofu to Terraform gets harder once you rely on OpenTofu-only features such as encrypted state, .tofu files or provider for_each. Moving from Terraform to OpenTofu gets harder with Terraform-only features such as Stacks, actions and list resources. See the OpenTofu migration guide.
Which One Should I Pick?¶
Start from the language your team will write, then from license and platform needs.
flowchart TD
Q1{"Write infrastructure in a<br/>general-purpose language?"}
Q1 -->|"Yes"| PU1["Pulumi<br/>(TypeScript, Python, Go, .NET, Java)"]
Q1 -->|"No, HCL"| Q2{"Need an OSI open-source license<br/>or foundation governance?"}
Q2 -->|"Yes"| OT1["OpenTofu<br/>(MPL-2.0, CNCF Sandbox)"]
Q2 -->|"No, BSL 1.1 is fine"| Q3{"Need HCP Terraform features:<br/>Stacks, Sentinel, HYOK?"}
Q3 -->|"Yes"| TF1["Terraform + HCP Terraform / TFE"]
Q3 -->|"No"| Q4{"Need client-side state encryption,<br/>provider for_each or OCI distribution?"}
Q4 -->|"Yes"| OT2["OpenTofu"]
Q4 -->|"No"| Q5{"Want Pulumi Cloud services<br/>(ESC, Neo, Deployments) with HCL?"}
Q5 -->|"Yes"| PU2["Pulumi HCL<br/>(runtime: hcl)"]
Q5 -->|"No"| EITHER["Terraform or OpenTofu:<br/>from 1.5.x, switching is drop-in"]
Decision Guide¶
| Scenario | Recommendation |
|---|---|
| Existing Terraform, no license concern | Terraform: stay put, largest ecosystem, HCP Terraform features |
| Existing Terraform 1.5.x or earlier, need an OSI license | OpenTofu: drop-in migration |
| Existing Terraform 1.6+, need an OSI license | OpenTofu after reviewing Terraform-only features in use |
| New project, developer-centric team | Pulumi: real languages, tests, IDE tooling |
| Regulated environment, state must be encrypted client-side | OpenTofu: native state and plan encryption; Terraform only via HYOK on HCP Terraform |
| Complex logic, self-service platform built on IaC | Pulumi: loops, classes, Automation API |
| Maximum provider coverage | Any of the three: they run the same Terraform-protocol providers |
| CNCF-aligned or vendor-neutral stack | OpenTofu: CNCF Sandbox, Linux Foundation |
Sources¶
- Terraform documentation, CHANGELOG and LICENSE (BSL 1.1, licensor IBM)
- HashiCorp pricing
- Terraform MCP server GA
- OpenTofu documentation, state and plan encryption and migration guide
- OpenTofu v1.12 CHANGELOG and CNCF project page
- OpenTofu MCP server
- Pulumi documentation, languages and SDKs, state and backends and pricing
- Using any Terraform provider with Pulumi
- Terraform GitHub, OpenTofu GitHub and Pulumi GitHub