Skip to main content

09 - Terraform vs Pulumi vs OpenTofu: Final Comparison 2026

Terraform IaC 15 min Terraform vs Pulumi vs OpenTofu: Confronto Definitivo 2026 Un confronto completo e imparziale tra i tre principali tool IaC del 2026:...

What do you think about this article?

At a Glance

Terraform IaC 15 min Terraform vs Pulumi vs OpenTofu: Confronto Definitivo 2026 Un confronto completo e imparziale tra i tre principali tool IaC del 2026:...

Terraform IaC 15 min

Terraform vs Pulumi vs OpenTofu: Definitive Comparison 2026

A comprehensive and unbiased comparison of the top three IaC tools of 2026: Terraform (HCL, 32.8% market share), Pulumi (TypeScript/Python/Go) and OpenTofu (open-source fork). When to choose which one.

Terraform vs Pulumi OpenTofu IaC Comparison HashiCorp License Pulumi

The IaC Panorama in 2026

In 2023, HashiCorp changed Terraform's license from MPL 2.0 (open-source) to Business Source License (BSL 1.1), sparking one of the most heated debates in the world DevOps. BSL is not open-source according to the OSI definition: commercial use is prohibited by direct competitors of HashiCorp. The community's response was immediate: open-source fork OpenTofu, then donated to the Linux Foundation.

In 2026, the market has settled into three clear positions: Terraform holds the 32.8% market share among IaC tools thanks to its huge installed base and the ecosystem of providers and modules; OpenTofu has conquered the ~8% mainly in environments that require certified open-source licenses; Pulumi and grew up at ~15% focusing on developer experience and native testing. CloudFormation, CDK, Bicep and Ansible complete the panorama.

What You Will Learn

  • History and implications of the HashiCorp BSL license change
  • OpenTofu: Terraform compatibility, current status and roadmap
  • Pulumi: "infrastructure as real code" paradigm, pros and cons
  • Technical comparison table: features, licensing, ecosystem, testing
  • Decision matrix: when to choose each tool
  • Migration from Terraform to OpenTofu: step-by-step procedure

The HashiCorp License Change: What It Means

The Business Source License (BSL 1.1) adopted by HashiCorp in 2023 has a clause key: You may not use the software to offer a commercial product that competes with HashiCorp. In practice, this means:

# Cosa e CONSENTITO con la BSL HashiCorp:
# - Uso interno in azienda per gestire infrastruttura propria
# - Contribuire al codebase Terraform
# - Creare moduli e provider Terraform
# - Usare Terraform in CI/CD per i tuoi progetti
# - Formazione e certificazioni

# Cosa NON e CONSENTITO senza licenza commerciale:
# - Offrire Terraform as a Service (competitor di Terraform Cloud/Enterprise)
# - Costruire un prodotto SaaS che "wrappa" Terraform come core feature
#   e compete con HCP Terraform
# - Le piattaforme come Spacelift, Env0, Scalr devono gestire questa zona grigia

# Data conversione a Apache 2.0: non annunciata (BSL diventa Apache 2.0 dopo 4 anni
# dalla release di ogni versione, quindi Terraform 1.5 -> Apache 2.0 nel 2027)

# Chi ha BIFORCATO:
# - OpenTofu (Linux Foundation, ex OpenTF) - replica di Terraform pre-BSL
# - OpenTofu segue Terraform con ~2-4 version lag
# - Attuale: OpenTofu 1.8.x vs Terraform 1.9.x

OpenTofu: The Open-Source Fork

OpenTofu (formerly OpenTF) and the retained Terraform fork from the Linux Foundation with contributions from Gruntwork, Spacelift, Env0, Scalr and dozens of others. Stated goal: to remain compatible with Terraform as it adds features that HCP may not implement to protect the business model.

Compatibility and Differences

# OpenTofu e un drop-in replacement per Terraform
# I file .tf sono identici: nessuna modifica richiesta per la maggior parte dei casi

# Installazione OpenTofu
# Via brew (macOS/Linux):
brew install opentofu

# Via script ufficiale:
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh | \
  sh -s -- --install-method standalone

# Verifica versione
tofu version
# OpenTofu v1.8.3
# on linux_amd64

# Comandi identici a Terraform (solo "tofu" invece di "terraform"):
tofu init
tofu plan
tofu apply
tofu destroy

# Stessa sintassi HCL, stessi provider, stesso state file format

Unique Features of OpenTofu (not in Terraform)

# 1. Encrypted State (OpenTofu 1.7+)
# Terraform richiede un backend esterno per la cifratura dello state
# OpenTofu supporta encryption nativa nel backend

terraform {
  encryption {
    key_provider "pbkdf2" "my_key" {
      passphrase = var.state_encryption_key
    }

    method "aes_gcm" "my_method" {
      keys = key_provider.pbkdf2.my_key
    }

    state {
      method = method.aes_gcm.my_method
    }

    plan {
      method = method.aes_gcm.my_method
    }
  }
}

# 2. Provider Functions (OpenTofu 1.7+, porting in Terraform 1.8)
# Funzioni custom definite nei provider (entrambi supportano ora)

# 3. Variable validation con references ad altre variabili
variable "max_instances" {
  type = number
}

variable "min_instances" {
  type = number
  validation {
    # OpenTofu: puoi referenziare altre variabili nella validation
    condition     = var.min_instances <= var.max_instances
    error_message = "min_instances deve essere <= max_instances."
  }
}

Migration from Terraform to OpenTofu

# Migrazione in 5 passi (praticamente indolore)

# 1. Backup dello state attuale
terraform state pull > backup_$(date +%Y%m%d).tfstate

# 2. Installa OpenTofu
brew install opentofu

# 3. Testa in un ambiente non-prod
cd environments/dev
tofu init   # Legge lo stesso .terraform.lock.hcl (OpenTofu e compatibile)
tofu plan   # Verifica che il plan sia identico a terraform plan

# 4. Se tutto ok, migra il .terraform.lock.hcl
# OpenTofu usa un formato leggermente diverso per il lock file
tofu providers lock \
  -platform=linux_amd64 \
  -platform=darwin_amd64 \
  -platform=darwin_arm64

# 5. Aggiorna le pipeline CI/CD
# Sostituisci "terraform" con "tofu" negli script
# Aggiorna le action GitHub se usi hashicorp/setup-terraform:
# usa opentofu/setup-opentofu invece

# Nel CI/CD (GitHub Actions):
# - name: Setup OpenTofu
#   uses: opentofu/setup-opentofu@v1
#   with:
#     tofu_version: "1.8.x"

Pulumi: Infrastructure As Real Code

Pulumi takes a radically different approach: instead of a declarative DSL (HCL), use real programming languages - TypeScript, Python, Go, C#, Java. This has profound implications: you have access to loops, conditionals, functions, npm/pip modules, native testing with Jest/pytest, and the entire language toolchain.

Pulumi in TypeScript

// Pulumi - infrastruttura come TypeScript
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";

const config = new pulumi.Config();
const environment = config.require("environment");
const instanceCount = config.requireNumber("instanceCount");

// VPC con subnet - stessa logica di Terraform ma con TypeScript
const vpc = new aws.ec2.Vpc("main", {
  cidrBlock: "10.0.0.0/16",
  enableDnsHostnames: true,
  enableDnsSupport: true,
  tags: {
    Name: `${environment}-vpc`,
    Environment: environment,
    ManagedBy: "Pulumi",
  },
});

// Crea subnet dinamicamente con un loop TypeScript nativo
// In Terraform useresti count o for_each
const publicSubnets = Array.from({ length: instanceCount }, (_, i) =>
  new aws.ec2.Subnet(`public-${i}`, {
    vpcId: vpc.id,
    cidrBlock: `10.0.${i}.0/24`,
    mapPublicIpOnLaunch: true,
    tags: { Name: `${environment}-public-${i + 1}` },
  })
);

// Output esportati
export const vpcId = vpc.id;
export const subnetIds = publicSubnets.map(s => s.id);

Native Testing with Pulumi

The most concrete advantage of Pulumi over Terraform is testing: you can write testing with standard Jest/pytest/Go testing, without Terratest or external frameworks.

// test/infra.test.ts - Unit test Pulumi con Jest
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Mock del provider AWS per i test (non fa chiamate reali)
pulumi.runtime.setMocks({
  newResource: (args) => {
    return {
      id: `${args.name}-id`,
      state: { ...args.inputs, id: `${args.name}-id` },
    };
  },
  call: (args) => ({ outputs: {} }),
});

describe("VPC Infrastructure", () => {
  let infra: typeof import("../index");

  beforeAll(async () => {
    infra = await import("../index");
  });

  test("VPC deve avere DNS abilitato", async () => {
    const vpc = await infra.vpc;
    const props = await vpc.enableDnsHostnames.apply(v => v);
    expect(props).toBe(true);
  });

  test("Numero subnet deve corrispondere alla configurazione", async () => {
    const subnets = await pulumi.all(infra.subnetIds).apply(ids => ids.length);
    const expectedCount = Number(process.env.INSTANCE_COUNT || 2);
    expect(subnets).toBe(expectedCount);
  });

  test("Subnet devono appartenere alla VPC", async () => {
    const vpcId = await infra.vpcId;
    // Verifica che ogni subnet abbia il VPC ID corretto
    expect(vpcId).toBeDefined();
    expect(vpcId).toMatch(/^vpc-/);
  });
});

Comparison Table: Terraform vs OpenTofu vs Pulumi

Feature-by-Feature Comparison (2026)

Features Terraform OpenTofu Pulumi
License BSL 1.1 MPL 2.0 Apache 2.0
Language HCL HCL TS/Python/Go/C#
AWS Providers 1200+ resources Same as TF ~900 resources
Native testing terraform test (1.6+) tofu test Jest/pytest/Go
State encryption Backend only Native (1.7+) Pulumi Cloud
Learning curve Low Low Average
Community & Docs Excellent Good Good

Decision Matrix: When to Choose Which

# Scegli TERRAFORM se:
# - Hai gia un team con esperienza HCL e non vuoi riformare
# - Lavori in un contesto enterprise con vendor support HashiCorp
# - Hai bisogno del massimo ecosistema di provider e moduli
# - Non hai requisiti di licenza open-source certificata
# - Usi Terraform Cloud o HCP per il backend di stato

# Scegli OPENTOFU se:
# - La licenza BSL e un problema (healthcare, govtech, open-source aziende)
# - Vuoi drop-in replacement con garanzia open-source a lungo termine
# - Usi gia Terraform e vuoi minimizzare il costo di migrazione
# - Hai bisogno di state encryption nativa (feature non in Terraform)
# - Il tuo company legal ha approvato MPL 2.0 ma non BSL

# Scegli PULUMI se:
# - Il tuo team e composto da developer (non solo DevOps) abituati a TypeScript/Python
# - Hai logica di configurazione complessa: loop, condizionali, validazioni rich
# - Vuoi testing nativo con framework di test standard senza Terratest
# - Stai costruendo un Internal Developer Platform e vuoi API programmatiche
# - Hai bisogno di astrazioni di alto livello (Pulumi Component Resources)

Interoperability: Using Terraform Provider in Pulumi

// Pulumi supporta tutti i provider Terraform via bridge
// Utile per provider non ancora disponibili nativamente in Pulumi

import * as pulumitf from "@pulumi/terraform";

// Usa qualsiasi provider Terraform (anche non ufficiale)
const provider = new pulumitf.Provider("custom-provider", {
  version: "1.2.3",
  // Equivalente di required_providers in Terraform
});

// Questa interoperabilita permette una migrazione graduale
// da Terraform a Pulumi senza dover aspettare che tutti i provider
// siano portati nativamente

Conclusions

There is no absolute winner in this competition: each tool excels in contexts different. Terraform remains the market leader with the richest ecosystem. OpenTofu e the rational choice for those who want Terraform compatibility with an open-source license. Pulumi and the future for developer-centric teams that want to unify infrastructure and application in a single code paradigm.

The Complete Series: Terraform and IaC

Try These Tools

Free developer tools related to this topic.

Commenti

Caricamento commenti...

Sign in to comment

Discuss this article in the community

Join the Telegram group to discuss with other developers, ask questions and share your experiences.

Did you like this article?

Explore other content on the blog or discover my projects