Ismat Samadov
  • Tags
  • About
14 min read/0 views

Terraform Is Legacy Now — Pulumi, CDKTF, and the Infrastructure-as-Real-Code Movement

HashiCorp changed the license, IBM bought them, CDKTF got deprecated. Terraform is becoming the COBOL of infrastructure. Here's what's replacing it.

InfrastructureCloudDevOpsOpinion

Related Articles

SLOs Changed How We Ship Software — Error Budgets, Burn Rates, and Why 99.99% Uptime Is a Lie

15 min read

Remote Work Killed Mentorship — How Senior Engineers Can Fix It

13 min read

The Staff Engineer Trap: Why the Best ICs Get Promoted Into Misery

14 min read

Enjoyed this article?

Get new posts delivered to your inbox. No spam, unsubscribe anytime.

On this page

  • The HCL Problem Nobody Wanted to Talk About
  • What Actually Happened: A Timeline
  • The Contenders: What's Actually Replacing Terraform
  • Pulumi: Infrastructure as Real Code
  • OpenTofu: Terraform Without HashiCorp
  • CDKTF: Dead on Arrival
  • AWS CDK: The Cloud-Specific Alternative
  • The Comparison Nobody Wants to Make Honestly
  • The Decision Framework
  • The Testing Gap That Changes Everything
  • Migration Realities
  • What Most Articles Get Wrong
  • What I Actually Think

© 2026 Ismat Samadov

RSS

HashiCorp changed Terraform's license from open source to Business Source License in August 2023. IBM bought HashiCorp for $6.4 billion in early 2025. And then HashiCorp deprecated CDKTF — their own answer to "HCL isn't a real programming language" — sunsetting it on December 10, 2025. Three body blows in two years.

Meanwhile, Pulumi doubled its revenue, launched an AI agent for infrastructure provisioning, and crossed 150,000 users. OpenTofu attracted 140+ organizations and 600+ individual pledges within months of launching. The IaC market is projected to grow from $1.32 billion in 2025 to $9.40 billion by 2034.

The ground is shifting under Terraform. Not because it stopped working — it still provisions infrastructure just fine — but because the ecosystem has outgrown a proprietary domain-specific language controlled by a corporation that's now a subsidiary of IBM.

The HCL Problem Nobody Wanted to Talk About

For years, the Terraform community treated HCL's limitations as a feature, not a bug. "It's declarative!" "It's simple!" "You don't need a real programming language to describe infrastructure!"

That was always a cope.

HCL pretends to be programming-light, but the second you need a loop, condition, or anything dynamic, you're forced to hack it via count, for_each, or ternary expressions that make Perl look readable. Try writing a conditional resource creation in HCL:

# HCL: Create a CloudWatch alarm only in production
resource "aws_cloudwatch_metric_alarm" "cpu" {
  count = var.environment == "production" ? 1 : 0

  alarm_name          = "high-cpu-${var.service_name}"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "CPUUtilization"
  namespace           = "AWS/ECS"
  period              = 300
  statistic           = "Average"
  threshold           = 80

  dimensions = {
    ClusterName = var.cluster_name
    ServiceName = var.service_name
  }
}

# Then reference it elsewhere with this beauty:
# aws_cloudwatch_metric_alarm.cpu[0].arn
# Hope you enjoy index-based access on optional resources!

Now the same thing in Pulumi with Python:

import pulumi_aws as aws

if environment == "production":
    alarm = aws.cloudwatch.MetricAlarm(
        "high-cpu",
        alarm_name=f"high-cpu-{service_name}",
        comparison_operator="GreaterThanThreshold",
        evaluation_periods=2,
        metric_name="CPUUtilization",
        namespace="AWS/ECS",
        period=300,
        statistic="Average",
        threshold=80,
        dimensions={
            "ClusterName": cluster_name,
            "ServiceName": service_name,
        },
    )

Just... Python. An if statement. No count tricks. No bracket-zero indexing. No ternary inside a resource block. The language does what languages do.

This isn't a trivial example. In real infrastructure code, the complexity compounds. A recent survey found that 75% of infrastructure stakeholders feel frustrated chasing configuration errors. Engineers spend evenings debugging HCL syntax instead of solving real problems.

And the cost is quantifiable. 51% of developers spend more than 20% of their time managing infrastructure code. At an average salary of $150,000, that's $30,000 per engineer per year. For a 10-person team, you're spending $300,000 annually to wrestle with a language that has no package manager, no testing framework, no IDE intelligence worth mentioning, and no way to share code that doesn't involve copy-pasting modules.

What Actually Happened: A Timeline

Let me lay out the sequence, because the full picture is worse than any individual event suggests.

August 2023: HashiCorp switches Terraform from MPL 2.0 (open source) to BSL 1.1 (not open source). The community gets zero advance notice. Competitors who built managed services on Terraform — Spacelift, env0, Scalr — are suddenly in legal jeopardy.

September 2023: A coalition of companies and individuals launches the OpenTofu initiative — a community fork of Terraform's last open-source version (1.6.x). It moves under the Linux Foundation.

January 2024: OpenTofu releases v1.6.0, its first stable release. It's production-ready and 100+ contributors join in six months.

April 2024: IBM announces it's acquiring HashiCorp for $6.4 billion. The community holds its breath. Will IBM restore open-source licensing?

2024: HashiCorp sends OpenTofu a cease-and-desist letter, alleging code theft. OpenTofu denies it, pointing to the MPL-licensed codebase they forked from. The dispute remains unresolved.

Early 2025: IBM closes the HashiCorp acquisition. No announcement about restoring open-source licensing. Silence on licensing questions, focus on commercial features.

2025: HashiCorp deprecates CDKTF, their answer to developers who wanted real programming languages. Sunset date: December 10, 2025. The stated reason: it "did not find product-market fit at scale."

Mid-2025: HashiCorp announces Terraform Open Source under BSL will be discontinued after July 2025.

That's the trajectory. A project that was once the undisputed open-source standard for infrastructure provisioning is now a proprietary IBM product with a deprecated programming-language layer, locked in a legal fight with its own community fork.

The Contenders: What's Actually Replacing Terraform

Pulumi: Infrastructure as Real Code

Pulumi's thesis is simple: infrastructure code should be actual code. Not a DSL. Not a configuration language. Python, TypeScript, Go, C#, Java — the languages your team already knows.

The difference isn't cosmetic. When your infrastructure is written in a real language, you get:

  • Real testing. Unit tests, integration tests, property-based testing — using pytest, Jest, or whatever framework your team already uses.
  • Real abstractions. Classes, functions, modules, packages. No more copy-pasting Terraform modules and hoping the variable names match.
  • Real package management. pip, npm, NuGet. Share infrastructure components like you share application libraries.
  • Real IDE support. Autocomplete, type checking, go-to-definition, refactoring tools. Your editor actually understands your infrastructure code.

Here's what provisioning an ECS service looks like in Pulumi with TypeScript:

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

// Real function. Real parameters. Real return type.
function createService(
  name: string,
  config: {
    image: string;
    cpu: number;
    memory: number;
    port: number;
    environment: Record<string, string>;
  }
) {
  const taskDefinition = new aws.ecs.TaskDefinition(`${name}-task`, {
    family: name,
    cpu: config.cpu.toString(),
    memory: config.memory.toString(),
    networkMode: "awsvpc",
    requiresCompatibilities: ["FARGATE"],
    containerDefinitions: JSON.stringify([{
      name,
      image: config.image,
      cpu: config.cpu,
      memory: config.memory,
      portMappings: [{ containerPort: config.port }],
      environment: Object.entries(config.environment).map(
        ([k, v]) => ({ name: k, value: v })
      ),
    }]),
  });

  const service = new aws.ecs.Service(`${name}-service`, {
    cluster: cluster.arn,
    taskDefinition: taskDefinition.arn,
    desiredCount: 2,
    launchType: "FARGATE",
    networkConfiguration: {
      subnets: privateSubnetIds,
      securityGroups: [serviceSecurityGroup.id],
    },
  });

  return { taskDefinition, service };
}

// Deploy three services with one function call each
const api = createService("api", {
  image: "my-registry/api:latest",
  cpu: 256, memory: 512, port: 8080,
  environment: { DATABASE_URL: dbUrl, REDIS_URL: redisUrl },
});

const worker = createService("worker", {
  image: "my-registry/worker:latest",
  cpu: 512, memory: 1024, port: 9090,
  environment: { QUEUE_URL: queueUrl },
});

Try doing that in HCL. You'll end up with three nearly identical resource blocks, a for_each that requires a map, and variable files that are longer than the actual infrastructure code.

Pulumi now counts over 2,000 customers and 150,000 users, with 45% year-over-year adoption growth. Their Series C brought total funding to $99 million. They launched Pulumi Neo, an agentic AI that provisions infrastructure from natural language descriptions with built-in governance and compliance guardrails. They built an MCP server that connects Claude, Copilot, and Cursor directly to the Pulumi registry.

The AI angle is significant. When your infrastructure is written in Python or TypeScript, LLMs can actually help — they've trained on millions of Python files. When it's in HCL, the LLM is working with a niche DSL that represents a tiny fraction of its training data.

OpenTofu: Terraform Without HashiCorp

OpenTofu is the continuity play. If you have thousands of lines of Terraform HCL and you're not ready to rewrite them in Python, OpenTofu is the answer: same language, same provider ecosystem, same workflow, no BSL license.

OpenTofu operates under Linux Foundation governance with a Technical Steering Committee drawn from multiple organizations. They've already shipped features Terraform hasn't — most notably state file encryption in v1.7, which was a top community request for years.

According to Spacelift's data, half of their deployments are already on OpenTofu. Oracle switched their EBS Cloud Manager from Terraform to OpenTofu. The project has committed to a minimum of 18 full-time developers over the next five years.

The migration is trivial — in most cases, you literally rename terraform to tofu in your commands and CI/CD pipelines:

# Before
terraform init
terraform plan
terraform apply

# After
tofu init
tofu plan
tofu apply

Configuration files, state files, and providers are compatible. The biggest risk isn't technical — it's whether OpenTofu can keep pace with Terraform's provider ecosystem as the two codebases diverge over time.

CDKTF: Dead on Arrival

I need to mention CDKTF because it was supposed to be the best-of-both-worlds solution: write in TypeScript or Python, generate Terraform HCL, use the Terraform provider ecosystem. HashiCorp's own answer to the "HCL sucks" complaint.

It was deprecated in 2025. HashiCorp's official statement: it "did not find product-market fit at scale."

The honest reason: CDKTF was always a leaky abstraction. You wrote TypeScript, but you still needed to understand Terraform internals — state management, provider quirks, plan/apply cycles. When something went wrong, you had to debug the generated HCL, not your TypeScript. And the generated HCL was unreadable.

If you're currently using CDKTF, you have two options: migrate to standard Terraform/HCL (HashiCorp's recommendation) or migrate to Pulumi (my recommendation). Going back to HCL feels like admitting defeat.

AWS CDK: The Cloud-Specific Alternative

AWS CDK deserves a mention because it's the only vendor-specific IaC tool that's actually gaining traction. It synthesizes to CloudFormation, supports TypeScript, Python, Java, C#, and Go, and AWS is actively investing in it — new features in 2025 include CDK Toolkit Library, CDK Refactor, and CDK Mixins.

The limitation is obvious: it only works with AWS. If you're multi-cloud or planning to be, AWS CDK locks you in harder than Terraform ever did.

The Comparison Nobody Wants to Make Honestly

FeatureTerraform/HCLOpenTofuPulumiAWS CDK
LanguageHCL (DSL)HCL (DSL)Python, TS, Go, C#, JavaTS, Python, Java, C#, Go
LicenseBSL 1.1 (proprietary)MPL 2.0 (open source)Apache 2.0 (open source)Apache 2.0 (open source)
Cloud SupportMulti-cloud (3000+ providers)Multi-cloud (Terraform-compatible)Multi-cloud (150+ providers)AWS only
State ManagementRemote backends (S3, etc.)Remote backends + encryptionPulumi Cloud or self-managedCloudFormation (managed)
TestingTerratest (Go, external)Terratest (Go, external)Native unit testing in any frameworkassertions, integ tests
IDE SupportLimited (VS Code extension)LimitedFull (type checking, autocomplete)Full
AI AssistanceLimited (niche DSL)LimitedStrong (general-purpose languages)Moderate
Learning CurveNew language to learnSame as TerraformUse languages you knowAWS + CDK concepts
Market Share~33%Growing (50% of Spacelift deploys)~12% (growing 45% YoY)AWS-only segment
BackingIBM/HashiCorpLinux FoundationPulumi Corp ($99M funded)AWS

The column that matters most depends on your situation. If you're choosing today, the license row should terrify you. BSL means IBM can change the terms of Terraform's usage whenever they want. Every other option on this table is genuinely open source.

The Decision Framework

Here's how I'd think about this if I were starting fresh or considering a migration:

Stay on Terraform/HCL if:

  • You have hundreds of thousands of lines of HCL that work
  • Your team is primarily ops-focused (not software engineers)
  • You're locked into Terraform Cloud/Enterprise and the migration cost exceeds the licensing risk
  • You've accepted the IBM/BSL situation and trust it won't change

Migrate to OpenTofu if:

  • You want open-source Terraform without the licensing risk
  • Your existing HCL codebase is large and working
  • You don't want to retrain your team on a new paradigm
  • You value community governance over corporate control

Migrate to Pulumi if:

  • Your infrastructure team includes software engineers (not just ops)
  • You're starting a new project or doing a significant infrastructure rewrite
  • You want real testing, real abstractions, and real IDE support
  • You're investing in AI-assisted development (LLMs work better with general-purpose languages)
  • You're tired of HCL and want to use languages your team already knows

Use AWS CDK if:

  • You're 100% AWS and intend to stay that way
  • Your team already knows CloudFormation concepts
  • You want AWS-native integration with no abstraction layer

The Testing Gap That Changes Everything

Here's something that gets glossed over in every "Terraform vs Pulumi" comparison: testing.

In Terraform, your testing options are grim. Terratest is written in Go (even if your team doesn't use Go), runs against real infrastructure (slow and expensive), and requires a separate test harness that doesn't share any code with your infrastructure definitions. Most teams don't bother. They terraform plan, eyeball the output, and pray.

In Pulumi, testing is native:

import pytest
import pulumi

class MyMocks(pulumi.runtime.Mocks):
    def new_resource(self, args):
        return [args.name + "_id", args.inputs]

    def call(self, args):
        return {}

pulumi.runtime.set_mocks(MyMocks())

from my_infra import s3_bucket, security_group

@pulumi.runtime.test
def test_bucket_is_private():
    def check_acl(acl):
        assert acl != "public-read", \
            "S3 bucket must not be publicly readable"
    return s3_bucket.acl.apply(check_acl)

@pulumi.runtime.test
def test_no_ssh_from_internet():
    def check_ingress(ingress):
        for rule in ingress:
            assert rule["cidr_blocks"] != ["0.0.0.0/0"] or \
                   rule["from_port"] != 22, \
                "SSH must not be open to the internet"
    return security_group.ingress.apply(check_ingress)

These tests run in milliseconds without provisioning anything. They catch security violations, policy violations, and configuration errors before the code ever touches AWS. You run them in CI alongside your application tests. No special infrastructure needed.

This is the gap that matters most in practice. When teams tell me "we had a production outage because someone opened port 22 to the world in a Terraform PR," my first question is: "Where were your tests?" And the answer is always the same — they didn't have any, because testing HCL is painful enough that nobody does it.

Migration Realities

Let me be honest about what migration actually looks like, because the blog posts from IaC vendors always make it sound easy.

OpenTofu migration (1-2 weeks): This is genuinely easy. Rename binaries, update CI/CD scripts, test in staging. The state file format is compatible. Your providers work. The main risk is provider version drift as the two ecosystems diverge — pin your provider versions and test before upgrading.

Pulumi migration (1-3 months for a mid-size codebase): This is a rewrite. Every Terraform resource becomes a Pulumi resource in your chosen language. Pulumi provides a pulumi convert command that converts HCL to Pulumi code, but the output is mechanical and needs human cleanup. Budget 1-2 days per module for conversion plus testing. The state migration requires importing existing resources into Pulumi's state.

The phased approach:

# Phase 1: Convert one module as a proof of concept
pulumi convert --from terraform --language python

# Phase 2: Import existing resources into Pulumi state
pulumi import aws:s3:Bucket my-bucket my-existing-bucket-name

# Phase 3: Validate with pulumi preview (like terraform plan)
pulumi preview

# Phase 4: Cut over when preview matches reality
pulumi up

The state migration is the hardest part. Your infrastructure already exists. You need to import every existing resource into Pulumi's state without destroying and recreating it. For 50 resources, this takes a day. For 500, it takes a week. For 5,000, budget a month.

What Most Articles Get Wrong

"Terraform is dead." It isn't. Terraform still holds 33% market share and 87% enterprise adoption among companies with 1,000+ employees. It has an ecosystem of 3,000+ providers that nobody else can match. Terraform isn't dead — it's becoming the COBOL of infrastructure. Still running, still critical, increasingly legacy.

"Pulumi is just Terraform with Python." No. The execution model is fundamentally different. Pulumi uses a real runtime — your code actually executes, and the Pulumi engine translates the resource declarations into API calls. This means you can use loops, conditionals, async/await, error handling, and every other feature of your language naturally. In Terraform, HCL is interpreted by the Terraform binary — your "code" is really configuration that gets evaluated in a constrained way.

"OpenTofu solved the license problem." Partially. OpenTofu solved the license problem for the code as it existed in 2023. As Terraform and OpenTofu diverge, new Terraform features won't appear in OpenTofu and vice versa. Provider compatibility may also diverge. OpenTofu is a fork, and forks have maintenance costs.

"Just use whatever your team knows." This is bad advice when the tool your team knows just changed its license, got acquired by IBM, and deprecated its modernization path. "What your team knows" is a valid factor, but it shouldn't override strategic technology decisions. Teams can learn new tools. Teams can't un-sign a BSL license agreement.

What I Actually Think

Terraform is legacy now. Not in the "it's broken" sense — in the "it's the safe, boring, increasingly constrained choice" sense. Like Java EE. Like SOAP. Like jQuery. It works. It'll keep working. But the energy, innovation, and community momentum are elsewhere.

The BSL license change was the inflection point. Before August 2023, Terraform was the obvious default — open source, massive ecosystem, battle-tested. After the license change, choosing Terraform means choosing a proprietary tool owned by IBM. That's a fundamentally different risk profile.

CDKTF's deprecation was the nail in the coffin. It was HashiCorp's acknowledgment that HCL is a limitation, and their solution didn't work. If HashiCorp themselves couldn't make "HCL but with programming languages" viable, that's a strong signal about HCL's future.

If I were starting a new project today, I'd choose Pulumi without hesitation. The developer experience is years ahead. The testing story is incomparably better. The AI-assisted development angle is a genuine advantage that will only grow. And the ecosystem, while smaller than Terraform's, covers all three major clouds and most common infrastructure patterns.

If I had an existing Terraform codebase, I'd migrate to OpenTofu immediately (it's a one-week project for most teams) and then evaluate Pulumi for new infrastructure. The OpenTofu migration eliminates the licensing risk while you plan a longer-term strategy.

The IaC market is heading toward real programming languages. That's the direction of every developer tool in every domain — from CSS-in-JS to infrastructure-as-TypeScript. The DSL era is ending. 74% of IT leaders believe IaC will be essential to their cloud strategy, and the version of IaC they're envisioning looks a lot more like Pulumi than like HCL.

Terraform had an incredible run. It genuinely changed how we think about infrastructure. But the future of infrastructure-as-code is infrastructure-as-actual-code — and that future doesn't run on HCL.


Sources: OpenTofu Manifesto, Spacelift — Terraform License Change, DevOps.com — IBM Confirms HashiCorp Acquisition, HashiCorp — CDKTF Documentation, Pulumi Series C Announcement, Pulumi 2025 Product Launches, InfoQ — Pulumi Neo Launch, Precedence Research — IaC Market Size, Dev.to — Terraform Licensing 2025 Strategy, Terraform vs Pulumi 2026 — Dev Journal, env0 — Pulumi vs Terraform Comparison, Shuttle — Infrastructure as Code Problems, Terracotta AI — Why Terraform is Still Hard, SlickFinch — Terraform vs OpenTofu Comparison, Medium — OpenTofu Complete Guide, DevOps.com — HashiCorp vs OpenTofu, Ned in the Cloud — IBM and HashiCorp, Medium — On IBM Acquiring HashiCorp, Towards The Cloud — AWS CDK vs Terraform 2026, SigNoz — Datadog Pricing, 360i Research — IaC Market Size.