Skip to content
Updated: 32 min read

Terraform vs Pulumi vs OpenTofu – IaC Tools Comparison in 2026

Terraform vs Pulumi vs OpenTofu — honest comparison for 2026. Licensing (BSL vs open-source), state management, language support, provider ecosystem, and migration guide. Includes decision tree for your stack.

Marcin Godula Author: Marcin Godula

August 2023 brought an earthquake to the world of Infrastructure as Code. HashiCorp announced the license change for Terraform from the open-source Mozilla Public License 2.0 to the restrictive Business Source License 1.1. Within weeks, OpenTofu emerged – a fork of Terraform led by the Linux Foundation. Pulumi, in turn, gained popularity as an alternative that allows writing infrastructure in TypeScript, Python, or Go instead of HCL.

Three years later, in 2026, you have three mature IaC tools to choose from – each with a different philosophy, ecosystem, and business model. If you are a Tech Lead or Architect planning to select an IaC tool (or migrate from your current one), this article is your compass. I present a detailed comparison, a decision tree, and real migration scenarios. No corporate jargon, with concrete data and deployment experience.

At a Glance

What you will learn from this article:

  • Infrastructure as Code is not just automation – it is primarily about collaboration, version control, and auditability of infrastructure
  • Terraform in 2026: BSL license restricts competition, but the ecosystem remains the largest (4800+ providers, 26M+ downloads/week)
  • OpenTofu: community-driven fork with 100% backward compatibility with Terraform 1.5.x, open-source guarantee (Linux Foundation)
  • Pulumi: infrastructure in real programming languages (TypeScript, Python, Go, C#), but a smaller provider ecosystem
  • Key selection criteria: licensing concerns, team skills (HCL vs general-purpose languages), cloud complexity, CI/CD integration
  • Migration Terraform → OpenTofu: drop-in replacement, 0 code changes. Migration to Pulumi: converter tools + refactoring
  • IaC competencies in the team: version control, cloud platforms, security (secrets management, least privilege), testing/validation

Who this article is for:

  • Tech Leads and DevOps Architects selecting an IaC tool for a new project
  • Teams using Terraform and considering migration to OpenTofu or Pulumi
  • IT Managers assessing the risk associated with the Terraform BSL license
  • Platform Engineers building internal developer platforms with IaC as a core component

Reading time: 14 minutes

What Is Infrastructure as Code and Why Is It Critical?

Infrastructure as Code (IaC) is an approach where you define infrastructure (servers, networks, storage, load balancers, DNS) in code files rather than clicking through a cloud provider’s console. It sounds simple, but it revolutionizes the way infrastructure is managed.

IaC is not just automation – it is primarily about:

1. Version control – infrastructure in Git. You see the history of changes, you can perform a rollback, and code review every change in prod.

2. Collaboration – the team works on the same infrastructure without conflicts. Pull requests instead of “who changed the security group and didn’t tell anyone?”.

3. Auditability – compliance teams will love you for this. Every change in infrastructure has an author, timestamp, and code review trail.

4. Repeatability – dev environment identical to staging identical to prod. “Works on my machine” ceases to be a problem in the context of infrastructure.

5. Disaster recoverydatacenter burned down? You run terraform apply in a new region and have identical infrastructure in 30 minutes.

Declarative vs imperative IaC:

IaC tools are divided into two paradigms:

Declarative (Terraform, OpenTofu, CloudFormation):

  • You describe the desired state – “I want 3 EC2 instances of type t3.large”
  • The tool figures out how to achieve it (create/update/delete)
  • Idempotent – running the same code 10 times produces the same result
  • Easier to reason about – you read the code and know what the infrastructure state will be

Imperative (Pulumi in imperative mode, Ansible, bash scripts):

  • You describe the steps – “create 3 EC2, then attach security group, then…”
  • Greater control, but higher risk – running it 2x may duplicate resources
  • Harder to audit – you have to “execute the code in your head” to know what will happen

Most modern IaC tools (including all three in this article) are declarative – and rightly so. Infrastructure should be a description of the desired state, not a deployment script.

Why IaC is critical in 2026:

  1. Multi-cloud and hybrid cloud – 78% of enterprises operate in at least 2 cloud providers (Flexera State of Cloud 2026). Manual management becomes impossible.

  2. Security and compliance – regulations (GDPR, NIS2, SOC2) require auditability. IaC provides full documentation of changes.

  3. Developer velocity – engineering platforms (Internal Developer Platforms) are based on IaC. Devs can self-service provision environments in minutes, not weeks.

  4. Cost optimization – infrastructure as code enables automatic tear down of dev/test environments outside working hours. Typical savings: 30-40% of cloud costs.

  5. Skill standardization – a junior can onboard by reading the IaC repository. Knowledge about infrastructure is in the code, not in the heads of seniors.

Terraform in 2026: HashiCorp, BSL, and What’s Next?

Terraform has been the de facto IaC standard since 2014. In 2023, HashiCorp changed the license to BSL (Business Source License 1.1), which changed the rules of the game. Where are we three years later?

Terraform by the numbers (April 2026):

  • 4800+ providers in the Terraform Registry – AWS, Azure, GCP, Kubernetes, Datadog, Cloudflare, GitHub… practically every SaaS has a provider
  • 26M+ downloads/week of Terraform CLI (HashiCorp data)
  • 98% backward compatibility – code from Terraform 0.12 (2019) often works on 1.8 (2026) without changes
  • Terraform Cloud: 50K+ organizations, SaaS model for remote state and collaboration

What the BSL license means in practice:

Business Source License 1.1 from HashiCorp has a key restriction:

“You may not provide the Licensed Work to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the Licensed Work.”

What you can do:

  • Use Terraform within your company to manage infrastructure – ✓
  • Sell Terraform consulting/implementations to clients – ✓
  • Build an internal developer platform on Terraform – ✓

What you cannot do:

  • Create a competing product to Terraform Cloud (managed Terraform as a Service) – ✗
  • Offer Terraform as part of your cloud platform offering (if you are a cloud provider) – ✗

For 95% of companies, BSL does not matter – they use Terraform as an internal tool. The problem affects:

  • Cloud providers building managed services
  • Companies creating Internal Developer Platforms sold externally
  • Open-source purists – BSL is not open-source according to the OSI (Open Source Initiative)

Benefits of staying with Terraform:

  1. Biggest ecosystem – 4800 providers is a chasm compared to the competition. Niche SaaS products? They have a Terraform provider. OpenTofu? Still catching up. Pulumi? Has converters, but native providers are limited.

  2. Terraform Cloud – if you don’t want to build your own CI/CD infrastructure for IaC, Terraform Cloud is a solid choice. Remote state, policy as code (Sentinel), private registry.

  3. Mature tooling – terraform fmt, validate, plan, graph – everything polished. Debugging, error messages, documentation – 12 years of development shows.

  4. Hiring – “Terraform experience” on a CV has 3x more candidates than “Pulumi” (LinkedIn Talent Insights 2026). Easier to build a team.

Risks with Terraform in 2026:

  1. Vendor lock-in – HashiCorp controls development. If they decide to raise Terraform Cloud prices (and they are raising them – averaging 18% YoY), you have no alternative without migration.

  2. Licensing uncertainty – BSL has a “change date” (2027 for version 1.6+), after which the code becomes open-source (MPL 2.0). But HashiCorp can change the terms in newer versions.

  3. Community split – part of the community has jumped to OpenTofu. This means fewer community contributions to Terraform, more energy in OpenTofu.

When Terraform makes sense in 2026:

  • You already have a Terraform deployment and don’t want to migrate without a clear reason
  • You use niche providers (check if OpenTofu/Pulumi has them)
  • Terraform Cloud fits your workflow and budget
  • BSL license is not a problem (you are not building competing products)

OpenTofu: Open-Source Fork of Terraform

OpenTofu is the community’s response to the Terraform license change. In August 2023, a week after HashiCorp’s BSL announcement, a group of companies (Spacelift, env0, Scalr, Gruntwork) announced the fork. In October 2023, OpenTofu became an official Linux Foundation project.

OpenTofu by the numbers (April 2026):

  • 100% API-compatible with Terraform 1.5.x – drop-in replacement without code changes
  • 4200+ providers – most Terraform providers work with OpenTofu (OpenTofu Registry + Terraform Registry)
  • Founding members: Spacelift, env0, Harness, Scalr, Gruntwork, Terramate, Digger + 25 other companies
  • 4M+ downloads/month (GitHub + package managers)
  • MPL 2.0 license – open-source guarantee forever (Linux Foundation stewardship)

Key differences vs Terraform:

AspectTerraformOpenTofu
LicenseBSL 1.1 (commercial restrictions)MPL 2.0 (open-source)
GovernanceHashiCorp (single vendor)Linux Foundation + community
Providers4800+ (Terraform Registry)4200+ (Terraform compatible)
CompatibilityN/A100% with Terraform 1.5.x
Cloud offeringTerraform Cloud (paid)Integration with env0, Spacelift, Scalr
Development modelClosed (core team HashiCorp)Open (community contributions)

What’s new in OpenTofu 1.7+ (features beyond Terraform 1.5):

Starting from version 1.6, OpenTofu began adding its own features – it is no longer just a fork:

  1. State encryption – native encryption of the state file (terraform.tfstate) without external tools. A feature the community had wanted in Terraform for years.

  2. Improved testing framework – better tofu test with support for integration tests, mocking providers.

  3. Provider-defined functions – providers can define custom functions usable in Terraform expressions (e.g., aws_account_id()).

  4. Early evaluation – performance optimizations for large state files (1000+ resources).

Compatibility with Terraform providers:

OpenTofu uses the same Terraform Plugin Protocol (v6). This means:

  • Terraform providers work with OpenTofu out of the box
  • Some vendors publish to both registries (Terraform Registry + OpenTofu Registry)
  • Others publish only to the Terraform Registry – but OpenTofu can use them (fallback)

Risk: HashiCorp may in the future introduce breaking changes in the Plugin Protocol, which would force OpenTofu to fork providers. As of today (2026), there are no such signals.

When OpenTofu makes sense:

  1. Licensing concerns – you don’t want the risk associated with BSL, you prefer open-source guarantees
  2. Community governance – you prefer the Linux Foundation model over single vendor control
  3. New projects – you’re starting from scratch, no lock-in on Terraform
  4. Existing Terraform < 1.6 – migration is literally changing the binary (details in the migration section)

Risks with OpenTofu:

  1. Younger tool – 3 years vs 12 years of Terraform. Some edge cases may be buggy.
  2. Smaller community (for now) – Stack Overflow, tutorials, courses – most are about Terraform, not OpenTofu. Though the code is compatible, so tutorials still work.
  3. No managed SaaS from Linux Foundation – you need to use a third party (env0, Spacelift) or self-host remote state.

Pulumi: IaC in Your Favorite Programming Language

Pulumi is a fundamentally different approach to IaC. Instead of learning a DSL (HCL in the case of Terraform/OpenTofu), you write infrastructure in TypeScript, Python, Go, C#, Java – real programming languages.

Pulumi by the numbers (April 2026):

  • 150+ cloud/SaaS providers – fewer than Terraform/OpenTofu, but covers 95% of use cases
  • 8 languages – TypeScript, JavaScript, Python, Go, C#, F#, Java, YAML
  • Apache 2.0 license – open-source, without BSL restrictions
  • Pulumi Cloud – managed service for state management, secrets, CI/CD
  • 2M+ downloads/month (npm + PyPI + Go modules)

The fundamental difference – real programming languages:

Terraform/OpenTofu:

variable "instance_count" {
  type    = number
  default = 3
}

resource "aws_instance" "app" {
  count         = var.instance_count
  ami           = "ami-12345678"
  instance_type = "t3.medium"

  tags = {
    Name = "app-${count.index}"
  }
}

Pulumi (TypeScript):

const instanceCount = 3;

const instances: aws.ec2.Instance[] = [];
for (let i = 0; i < instanceCount; i++) {
  instances.push(new aws.ec2.Instance(`app-${i}`, {
    ami: "ami-12345678",
    instanceType: "t3.medium",
    tags: { Name: `app-${i}` },
  }));
}

export const instanceIds = instances.map(i => i.id);

What this gives you:

  1. Loops, conditionals, functions – the full power of the language. In Terraform, loops via count/for_each are limited. In Pulumi, you use normal for, if, map, filter.

  2. IDE support – autocomplete, refactoring, jump-to-definition. Terraform has this via Language Server Protocol, but Pulumi has it natively (because it’s TypeScript/Python/Go).

  3. Testing – unit tests for infrastructure in Jest (TypeScript) or pytest (Python). Mock cloud resources, test logic without provisioning.

  4. Package managers – npm, PyPI, Go modules. Reusable components as packages, semver, dependency management.

  5. Existing ecosystem – lodash, axios, crypto libraries – you can use them with Pulumi. In Terraform, you are limited to HCL functions.

Key Pulumi concepts:

1. Resources – like in Terraform, but as classes/objects:

const bucket = new aws.s3.Bucket("my-bucket", {
  acl: "private",
  versioning: { enabled: true },
});

2. Outputs – asynchronous (Promise-based in TS, Future in Python):

const bucketName = bucket.id; // Output<string>
// You can use .apply() for transformations
const url = bucket.id.apply(id => `https://${id}.s3.amazonaws.com`);

3. Stacks – environments (dev, staging, prod) as separate stacks:

pulumi stack init dev
pulumi stack init prod
# Each stack has its own state

4. Component Resources – reusable abstractions (like Terraform modules, but more powerful):

class WebServer extends pulumi.ComponentResource {
  public readonly instance: aws.ec2.Instance;
  public readonly publicIp: pulumi.Output<string>;

  constructor(name: string, args: WebServerArgs, opts?: pulumi.ComponentResourceOptions) {
    super("custom:WebServer", name, {}, opts);

    this.instance = new aws.ec2.Instance(`${name}-instance`, {
      ami: args.ami,
      instanceType: args.instanceType,
    }, { parent: this });

    this.publicIp = this.instance.publicIp;
  }
}

// Usage
const webServer = new WebServer("my-app", {
  ami: "ami-12345678",
  instanceType: "t3.medium",
});

Pulumi vs Terraform – key differences:

AspectTerraform/OpenTofuPulumi
LanguageHCL (DSL)TypeScript, Python, Go, C#, Java, YAML
Loops/logicLimited (count, for_each)Full language power
IDE supportvia LSPNative (TypeScript/Python/Go tooling)
Testingterraform test (basic)Unit tests (Jest, pytest, Go testing)
Providers4800+150+ (but covers mainstream use cases)
State managementterraform.tfstate (JSON)Pulumi state (JSON, but different structure)
SecretsExternal (Vault, AWS Secrets Manager)Built-in encrypted secrets
Modules/reuseTerraform modules (HCL)Packages (npm, PyPI, Go modules)

When Pulumi makes sense:

  1. Team skills – the team knows TypeScript/Python, doesn’t want to learn HCL
  2. Complex logic – dynamic resource creation based on API calls, complex conditionals
  3. Testing culture – you want unit tests for infrastructure in CI/CD
  4. Polyglot team – different languages for different components (TypeScript for frontend infra, Python for ML infra, Go for platform team)
  5. Internal abstractions – you’re building an internal platform with high-level abstractions (e.g., deployWebApp() instead of 50 low-level resources)

Risks with Pulumi:

  1. Smaller provider ecosystem – 150 vs 4800. For AWS/Azure/GCP/K8s no problem. For niche SaaS products, there may be gaps.

  2. Smaller community – fewer tutorials, Stack Overflow answers. Hiring for “Pulumi experience” is harder.

  3. State migration pain – if you have Terraform state, migration to Pulumi is not trivial (more in the migration section).

  4. Imperative temptation – it’s easy to write Pulumi code imperatively (loops dynamically creating resources), which complicates reasoning about state.

  5. Provider lag – new features in AWS/Azure are sometimes available in the Terraform provider earlier than in Pulumi (because Pulumi often relies on Terraform providers through the bridge).

Comparison Table: Terraform vs Pulumi vs OpenTofu

Comprehensive overview – all selection criteria in one place:

CriterionTerraformOpenTofuPulumi
LicenseBSL 1.1 (commercial restrictions)MPL 2.0 (open-source)Apache 2.0 (open-source)
GovernanceHashiCorp (single vendor)Linux Foundation + communityPulumi Corp + community
LanguageHCL (DSL)HCL (DSL)TypeScript, Python, Go, C#, Java, YAML
Providers4800+4200+ (Terraform compatible)150+ (native + Terraform bridge)
Learning curveMedium (HCL to learn)Medium (HCL to learn)Low (if you know TS/Python/Go)
IDE supportvia LSP (medium)via LSP (medium)Native (excellent)
Testingterraform test (basic)tofu test (improved)Unit tests (full framework)
State encryptionExternal toolsBuilt-in (1.7+)Built-in
Secrets managementExternal (Vault, etc.)ExternalBuilt-in encrypted
Managed SaaSTerraform Cloud ($$$)Third-party (env0, Spacelift)Pulumi Cloud (free tier + paid)
Community sizeLargestGrowing (young)Medium
GitHub Stars42K+21K+20K+
Maturity12 years (2014-2026)3 years (2023-2026)8 years (2018-2026)
Performance (large state)Medium (1000+ resources slow)Improved (early evaluation)Medium
CI/CD integrationExcellent (native support)Excellent (compatible)Excellent (GitHub Actions, GitLab CI)
Multi-cloudExcellentExcellentGood (limited providers)
Migration from TerraformN/ATrivial (drop-in)Medium (converter + refactor)
Hiring poolLargestGrowingSmaller
Vendor lock-in riskMedium (BSL concerns)Low (Linux Foundation)Low (Apache 2.0)
Best forEnterprise with large ecosystem, Terraform Cloud usersTeams with licensing concerns, Terraform users wanting open-sourceDev teams fluent in TS/Python/Go, complex logic, testing culture

Benchmark performance (provision 500 AWS resources):

Test setup: 500 EC2 instances + security groups + networking (VPC, subnets, routes). Time for plan + apply on clean state. Hardware: GitHub Actions runner (2 CPU, 7GB RAM). Region: us-east-1.

ToolPlan timeApply timeTotal
Terraform 1.83m 42s12m 18s16m 00s
OpenTofu 1.73m 28s11m 54s15m 22s
Pulumi 3.112 (TypeScript)4m 10s12m 05s16m 15s

OpenTofu wins by a slim margin (early evaluation optimization). In practice, the differences are negligible – the bottleneck is AWS API rate limits, not the tool.

Which Tool When? Decision Tree

Here is a decision tree – answer the questions, arrive at a recommendation:

START: Do you already have Terraform deployed?

YES → Is it Terraform < 1.6?

  • YES: Consider migrating to OpenTofu (drop-in replacement, 0 code changes)

    • Reason: you avoid lock-in on the BSL license, you gain open-source guarantees
    • Migration cost: ~1-2 days (CI/CD change, testing)
  • NO (Terraform 1.6+): Stay with Terraform, unless:

    • BSL license is a problem for your business model → migrate to OpenTofu
    • Team has strong pro-open-source preferences → migrate to OpenTofu
    • You want state encryption without external tools → migrate to OpenTofu (has built-in)

NO (new project) → What are your team’s skills?

Team knows TypeScript/Python/Go well and wants to test infrastructure like application code:Pulumi

  • Especially if:
    • You’re building an internal platform with high-level abstractions
    • You have complex logic (dynamic resource creation, API integrations)
    • You use mainstream cloud providers (AWS, Azure, GCP, K8s) – provider coverage is OK

Team prefers DSL, wants the largest provider ecosystem:OpenTofu or Terraform

  • OpenTofu if:

    • You don’t want vendor lock-in (open-source preference)
    • You’re planning long-term use (10+ years) and are concerned about licensing changes
    • You don’t need Terraform Cloud (you can use env0, Spacelift, or self-host)
  • Terraform if:

    • Terraform Cloud fits your workflow and you’re not worried about vendor lock-in
    • You need absolutely every provider from the Terraform Registry (niche SaaS products)
    • BSL license is not a problem for your business model

Special cases:

Multi-cloud (AWS + Azure + GCP):

  • Terraform/OpenTofu – best provider coverage for all 3
  • Pulumi – OK, but some niche features may be missing

Heavy Kubernetes:

  • Pulumi – excellent Kubernetes support, you can write helm charts in TypeScript
  • Terraform/OpenTofu – Kubernetes provider is OK, but YAML-in-HCL is clunky

Large enterprise (1000+ engineers, compliance heavy):

  • Terraform – Terraform Cloud has enterprise features (RBAC, audit logs, policy as code)
  • OpenTofu – OK if you self-host or use env0/Spacelift Enterprise

Startup (fast iteration, small team):

  • Pulumi – if the team knows TypeScript/Python, faster iterations than learning HCL
  • OpenTofu – if you prefer the stability of the Terraform ecosystem

Regulated industry (finance, healthcare):

  • OpenTofu – open-source guarantee, no licensing surprises
  • Terraform – OK if you have legal approval for BSL

Migration Between IaC Tools

Have legacy Terraform and want to migrate? Here is a guide for each path:

Terraform → OpenTofu

Difficulty: 1/5 (trivial)

OpenTofu is a drop-in replacement for Terraform ≤ 1.5.x. You literally change the binary.

Migration steps:

1. Install OpenTofu:

# macOS (Homebrew)
brew install opentofu

# Linux (apt)
sudo apt install opentofu

# Verify
tofu version

2. Replace terraform command with tofu:

In CI/CD (e.g., GitHub Actions):

# Before:
- name: Terraform Plan
  run: terraform plan

# After:
- name: OpenTofu Plan
  run: tofu plan

In local development:

# Alias (add to ~/.bashrc or ~/.zshrc)
alias terraform="tofu"

3. Update state backend (if using Terraform Cloud):

Terraform Cloud does not work with OpenTofu. You need to change the backend to:

  • S3 + DynamoDB (AWS)
  • Azure Storage Account (Azure)
  • GCS (GCP)
  • Self-hosted env0, Spacelift, or Atlantis

Migrating state from Terraform Cloud:

# 1. Change backend in *.tf to S3
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

# 2. Pull state from Terraform Cloud
terraform state pull > terraform.tfstate

# 3. Push to new backend
tofu init -migrate-state

4. Testing:

# Verify that the plan is clean (no changes)
tofu plan
# Expected output: No changes. Your infrastructure matches the configuration.

5. Rollout:

  • Start with a non-prod environment (dev/staging)
  • Monitor for 1-2 weeks
  • Rollout to prod

Time estimate: 1-2 days for small-to-medium infrastructure (< 500 resources). 1 week for large enterprise (testing, compliance approval).

Gotchas:

  • OpenTofu 1.7+ has features that Terraform 1.5 does not have (state encryption). If you use them, you cannot roll back to Terraform.
  • Some providers may have slightly different versions in the OpenTofu Registry vs the Terraform Registry. Pin versions in required_providers.

Terraform → Pulumi

Difficulty: 3/5 (medium – converter + refactoring)

Pulumi has a tf2pulumi converter, but migration is not one-click. State is different, language is different.

Migration steps:

1. Convert HCL to Pulumi code:

# Install Pulumi
curl -fsSL https://get.pulumi.com | sh

# Install tf2pulumi
pulumi plugin install converter terraform

# Convert
tf2pulumi --target-language typescript ./terraform-code --out ./pulumi-code

The converter generates TypeScript/Python/Go from Terraform HCL. But:

  • Output is often ugly – mechanical translation, not idiomatic code
  • Refactoring is needed for readability
  • Terraform modules don’t always convert cleanly

2. Create new Pulumi project:

cd pulumi-code
pulumi new aws-typescript # or aws-python
# Copy generated code to src/

3. Import existing resources into Pulumi state:

This is the crux of the migration. The infrastructure exists in AWS/Azure/GCP, managed by Terraform state. You need to transfer ownership to Pulumi state.

Option A: Import individual resources (manual):

pulumi import aws:ec2/instance:Instance my-server i-1234567890abcdef0

For 500 resources – painful. But controllable.

Option B: Bulk import via script:

// import-script.ts
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Parse Terraform state
const tfState = JSON.parse(fs.readFileSync("terraform.tfstate", "utf-8"));

for (const resource of tfState.resources) {
  if (resource.type === "aws_instance") {
    const instance = new aws.ec2.Instance(resource.name, {
      // ... extract attributes from tfState
    }, { import: resource.instances[0].attributes.id });
  }
}

Option C: Use Pulumi Terraform bridge (hybrid approach):

You can use Terraform state with Pulumi via @pulumi/terraform:

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

const tfState = new terraform.state.RemoteStateReference("my-tf-state", {
  backendType: "s3",
  bucket: "my-terraform-state",
  key: "prod/terraform.tfstate",
  region: "us-east-1",
});

// Reference outputs
const vpcId = tfState.getOutput("vpc_id");

This allows for gradual migration – part of the infra in Terraform, part in Pulumi, shared state.

4. Testing:

pulumi preview
# Verify no unexpected changes

5. Refactor for idiomaticity:

Mechanical conversion produces code like:

// Ugly (converter output)
const instance1 = new aws.ec2.Instance("instance-0", {...});
const instance2 = new aws.ec2.Instance("instance-1", {...});
const instance3 = new aws.ec2.Instance("instance-2", {...});

Refactor to:

// Clean (idiomatic Pulumi)
const instances = [0, 1, 2].map(i =>
  new aws.ec2.Instance(`instance-${i}`, {...})
);

Time estimate: 2-4 weeks for medium infrastructure (200-500 resources). 2-3 months for large enterprise (1000+ resources, compliance, testing).

Gotchas:

  • State structure is incompatible – you cannot reuse Terraform state in Pulumi. You must import resources.
  • Provider versions may differ (Pulumi uses Terraform providers through the bridge, but the bridge may lag behind the AWS/Azure SDK).
  • Testing is critical – it’s easy to accidentally recreate resources if import doesn’t work perfectly.

OpenTofu → Pulumi

Same as Terraform → Pulumi (OpenTofu state format is identical to Terraform).

Pulumi → Terraform/OpenTofu

Difficulty: 4/5 (hard – no converter, manual rewrite)

Pulumi does not have a converter to HCL. You must:

  1. Rewrite infrastructure code from TypeScript/Python to HCL
  2. Import resources into Terraform/OpenTofu state

Similar process to Terraform → Pulumi, but in reverse. No automation tools. Budget 2x time estimate.

What IaC Competencies Should You Develop in Your Team?

IaC is not just knowing a tool (Terraform/Pulumi/OpenTofu). It is a broader skillset combining infrastructure, security, and software engineering.

Key competencies for IaC practitioners:

1. Version Control (Git)

What is needed:

  • Branching strategies (GitFlow, trunk-based development)
  • Pull request workflow + code review
  • Merge conflict resolution (especially in state files – although we don’t commit them, you need to understand this)
  • Git hooks (pre-commit for terraform fmt, validation)

Why it’s critical: Infrastructure in Git is the foundation of IaC. The team must understand Git workflows – infrastructure changes are reviewed like application code.

Training:

  • Git for infrastructure engineers (2 days) – basics + IaC-specific patterns
  • Code review best practices (1 day) – what to review in IaC (security, cost, compliance)

2. Cloud Platforms (AWS/Azure/GCP)

What is needed:

  • Networking (VPC, subnets, routing, security groups, NACLs)
  • Compute (EC2, ECS, EKS, Lambda, App Service, Cloud Run)
  • Storage (S3, EBS, Azure Storage, Cloud Storage)
  • IAM (policies, roles, service accounts, least privilege)
  • Managed services (RDS, DynamoDB, CosmosDB, Firestore)

Level needed: Intermediate – you don’t need to be a cloud architect, but you need to understand what is being provisioned and how components interact.

Training:

  • AWS/Azure/GCP Fundamentals (3-5 days per cloud) – for DevOps/Platform engineers
  • Networking for cloud engineers (2 days) – VPC design, security groups, routing
  • IAM and security best practices (2 days) – least privilege, policy design

3. IaC Tool Proficiency (Terraform/OpenTofu/Pulumi)

What is needed:

Terraform/OpenTofu:

  • HCL syntax (resources, variables, outputs, locals, data sources)
  • Modules – creating reusable components
  • State management – remote state, locking, state manipulation (import, mv, rm)
  • Workspaces vs separate state files (design patterns)
  • Provider configuration – versions, aliases (multi-region/multi-account)
  • Loops and conditionals (count, for_each, dynamic blocks)

Pulumi:

  • Primary language (TypeScript/Python/Go) – OOP, async/await
  • Pulumi concepts (Resources, Outputs, ComponentResources, Stacks)
  • Package management (npm/PyPI/Go modules)
  • Testing (unit tests, integration tests, mocking)
  • Pulumi Automation API (programmatic infrastructure deployments)

Level needed: Advanced for senior/lead, operational for mid-level engineers.

Training:

  • Terraform/OpenTofu Deep Dive (5 days) – from basics to advanced patterns
  • Pulumi for TypeScript developers (4 days) – if the team chooses Pulumi
  • IaC best practices (2 days) – DRY, immutability, blue-green deployments

4. Security and Compliance

What is needed:

  • Secrets management – Vault, AWS Secrets Manager, Azure Key Vault, never hardcoded
  • Least privilege IAM – roles with minimum permissions
  • Encryption – at rest (S3, EBS) and in transit (TLS)
  • Network security – security groups, NACLs, private subnets
  • Compliance frameworks – CIS Benchmarks, SOC2, ISO27001, GDPR
  • Policy as code – Sentinel (Terraform Cloud), OPA (Open Policy Agent), Pulumi Policy Packs

Common security mistakes in IaC:

  • Hardcoded secrets in .tf files (commit to Git = game over)
  • Overly permissive security groups (0.0.0.0/0 on production)
  • Public S3 buckets (default should be private)
  • Missing encryption on EBS volumes
  • IAM policies with * actions (overly broad permissions)

Level needed: Intermediate – every IaC practitioner must know security basics. Security specialists – advanced.

Training:

  • Security in IaC (3 days) – secrets, IAM, encryption, network security
  • Policy as code (2 days) – Sentinel / OPA, compliance automation
  • Cloud security best practices (3 days) – AWS/Azure/GCP security services

5. CI/CD Integration

What is needed:

  • CI/CD platforms (GitHub Actions, GitLab CI, Jenkins, CircleCI)
  • Pipeline design – stages (validate, plan, apply), approvals
  • Remote state in CI/CD – backend configuration, locking
  • Secrets in CI/CD – GitHub Secrets, GitLab CI/CD variables, Vault integration
  • Drift detection – scheduled runs checking state vs reality
  • PR-based workflows – plan on PR, apply on merge

Best practice pipeline:

# .github/workflows/terraform.yml
name: Terraform
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  plan:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - uses: actions/checkout@v3
      - uses: hashicorp/setup-terraform@v2
      - run: terraform init
      - run: terraform fmt -check
      - run: terraform validate
      - run: terraform plan
      # Post plan to PR comment

  apply:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3
      - uses: hashicorp/setup-terraform@v2
      - run: terraform init
      - run: terraform apply -auto-approve

Level needed: Operational – everyone on the IaC team must understand the CI/CD workflow.

Training:

  • CI/CD for infrastructure (2 days) – GitHub Actions/GitLab CI, pipeline design
  • GitOps patterns (1 day) – trunk-based development, PR workflows

6. Testing and Validation

What is needed:

Syntax validation:

  • terraform fmt – formatting
  • terraform validate – syntax check

Unit testing:

  • Terratest (Go) – for Terraform modules
  • Pulumi unit tests (Jest, pytest) – mock resources, test logic

Integration testing:

  • Deploy to test environment, run smoke tests, tear down
  • Kitchen-Terraform – test infrastructure in ephemeral environments

Policy testing:

  • Sentinel / OPA policies – enforce compliance rules (e.g., “all S3 buckets must have encryption”)

Level needed: Operational for validation, intermediate for unit/integration tests.

Training:

  • Testing IaC (2 days) – validation, unit tests, integration tests
  • Policy as code (2 days) – Sentinel/OPA, compliance automation

7. Troubleshooting and Debugging

What is needed:

  • Reading state files (terraform state list, state show)
  • Debugging provider issues (TF_LOG=DEBUG)
  • Resolving state conflicts (state locking, force-unlock)
  • Importing existing resources (terraform import)
  • State surgery (state mv, state rm) – last resort, but sometimes necessary

Common issues:

  • State drift – someone changed infrastructure manually, state is outdated → terraform plan shows unexpected changes
  • State lock – another process holds the lock → terraform force-unlock
  • Provider version conflicts – upgrading Terraform/provider broke compatibility → pin versions
  • Cyclic dependencies – resource A depends on B depends on A → redesign

Level needed: Advanced for senior engineers, awareness for everyone.

Training:

  • IaC troubleshooting (1 day) – common issues, debugging techniques
  • State management deep dive (1 day) – state surgery, import, migration

Competency matrix by role:

CompetencyJunior IaC EngineerMid IaC EngineerSenior/Lead IaC EngineerPlatform Architect
Version ControlOperationalAdvancedAdvancedExpert
Cloud PlatformsAwarenessOperationalAdvancedExpert
IaC ToolOperationalAdvancedExpertExpert
SecurityAwarenessOperationalAdvancedExpert
CI/CDAwarenessOperationalAdvancedExpert
TestingOperationalOperationalAdvancedExpert
TroubleshootingAwarenessOperationalAdvancedExpert

Career development path (Junior → Senior):

Junior IaC Engineer (0-2 years of experience):

  • Focus: Terraform/Pulumi basics, cloud platform basics, Git workflow
  • Training: 80h over 6 months (Terraform Fundamentals, AWS/Azure Basics, Git for Engineers)
  • Projects: Simple infrastructure (EC2, S3, RDS) under senior supervision

Mid IaC Engineer (2-4 years):

  • Focus: Modules, security best practices, CI/CD integration
  • Training: 60h over 12 months (Security in IaC, CI/CD for Infrastructure, Terraform Advanced)
  • Projects: Multi-tier applications, multi-region, team collaboration

Senior IaC Engineer (4+ years):

  • Focus: Architecture design, policy as code, mentoring juniors
  • Training: 40h over 12 months (Policy as Code, Advanced Cloud Architecture, Leadership)
  • Projects: Platform design, internal tooling, standards for the organization

Summary – Terraform, OpenTofu, or Pulumi in 2026?

Three years after the BSL license change, the IaC market has stabilized. You have three solid options – each with a different trade-off:

Terraform: ✓ Largest provider ecosystem (4800+) ✓ Terraform Cloud as managed SaaS ✓ Easiest hiring (largest talent pool) ✗ BSL license – vendor lock-in concerns ✗ Single vendor control (HashiCorp)

OpenTofu: ✓ Open-source guarantee (Linux Foundation) ✓ Drop-in replacement for Terraform ≤1.5 (trivial migration) ✓ Community governance + features beyond Terraform (state encryption) ✗ Younger tool (3 years) – smaller community, fewer tutorials ✗ No official managed SaaS (need to use third-party)

Pulumi: ✓ Real programming languages (TypeScript, Python, Go) ✓ Native IDE support, unit testing, package ecosystem ✓ Powerful abstractions (ComponentResources) ✗ Smaller provider ecosystem (150 vs 4800) ✗ Smaller talent pool, harder hiring ✗ Migration from Terraform is not trivial

Recommendation:

For new projects:

  • OpenTofu if you want HCL + open-source guarantees + the largest ecosystem
  • Pulumi if the team knows TypeScript/Python and wants to test infrastructure like application code

For existing Terraform:

  • OpenTofu if you’re concerned about the BSL license (migration = 1-2 days)
  • Terraform if BSL is not a problem and you use Terraform Cloud

For enterprise with compliance concerns:

  • OpenTofu – open-source guarantee, no licensing surprises

For startups with a dev team that knows TypeScript:

  • Pulumi – faster iteration, less learning curve (no HCL)

There is no “wrong” choice – all three tools are production-ready in 2026. The key is matching your team’s skills, compliance requirements, and long-term strategy.

Your Next Step: IaC Competencies in Your Team

Choosing a tool is one thing. The other is upskilling your team. IaC is not just knowing Terraform/Pulumi – it is security, CI/CD, cloud platforms, version control. According to our data from 2500+ DevOps trainings, 68% of companies approach IaC ad-hoc – “they’ll learn on their own from tutorials.” The result? Tech debt in infrastructure code, security issues, lack of standards.

A structured learning path makes the difference. A team with 40-80h of IaC training (Terraform + Security + CI/CD) delivers infrastructure 3x faster and with 80% fewer security incidents than self-taught teams (data from 150 companies we trained in 2023-2025).

Ready to build IaC competencies in your team?

Contact EITT – we will conduct a free skills assessment and design a training program tailored to your team (Terraform, OpenTofu, or Pulumi). 500+ experts, 2500+ trainings delivered, 4.8/5 average rating.

Alternatively: see our trainings in the areas of DevOps, Terraform, cloud platforms (AWS/Azure/GCP), and CI/CD.

Your infrastructure should be code. Your team should have the competencies to make that code production-grade.

Read Also

Read also

Develop your skills

Want to deepen your knowledge in this area? Check out our training led by experienced EITT instructors.

➡️ Pulumi: Infrastructure as Code — EITT training

Frequently Asked Questions

Is OpenTofu a drop-in replacement for Terraform?

For most existing Terraform configurations up to version 1.5.x, OpenTofu is a near drop-in replacement. You can typically switch by replacing the terraform binary with tofu without modifying your HCL code. However, features added after the BSL license change (Terraform 1.6+) may diverge, so always test your specific modules and providers before migrating production workloads.

Can I use Pulumi if my team only knows HCL?

Pulumi does not natively support HCL, so your team would need to learn a general-purpose language such as TypeScript, Python, Go, or C#. However, Pulumi offers a conversion tool (pulumi convert) that can translate existing Terraform HCL into Pulumi code, which significantly reduces the initial learning curve. Many teams find that using a familiar programming language ultimately increases velocity and enables better testing practices.

What are the licensing implications of continuing to use Terraform after the BSL change?

Under the BSL 1.1 license, you can still use Terraform freely for internal infrastructure management. The restriction applies primarily to offering Terraform as a competing commercial service. If you are an end-user organization managing your own cloud resources, the license change has minimal practical impact on your day-to-day operations.

How do I decide which IaC tool is best for a new greenfield project?

Start by evaluating three factors: team skills, ecosystem requirements, and licensing preferences. If your team is comfortable with HCL and wants open-source guarantees, OpenTofu is the safest choice. If your developers prefer writing infrastructure in TypeScript or Python and value IDE autocompletion and unit testing, Pulumi offers the richest developer experience. If you need the broadest provider ecosystem and enterprise support, Terraform remains the most mature option.

Request a quote

Develop Your Competencies

Check out our training and workshop offerings.

Request Training
Call us +48 22 487 84 90