Posted on :: 1974 Words :: Tags: , , , ,

CDKTF is Dead: What Now?

Well, that didn't last long.

On December 10, 2025, HashiCorp pulled the plug on CDKTF (Cloud Development Kit for Terraform). Not just deprecated—they archived the entire repository on the same day. No grace period, no transition plan, just "it's done."

If you bet on CDKTF for your infrastructure, I'm sorry. Let's talk about what happened and how to get out of this mess.

Quick Recap: What Was CDKTF?

CDKTF was HashiCorp's attempt to let you write Terraform infrastructure using actual programming languages instead of HCL. The pitch was simple: if you hate YAML (who doesn't?) and find HCL limiting, just write TypeScript instead.

// CDKTF in TypeScript
import { App, TerraformStack } from "cdktf";
import { AwsProvider } from "@cdktf/provider-aws";
import { Instance } from "@cdktf/provider-aws/lib/instance";

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    new AwsProvider(this, "aws", { region: "us-west-2" });

    new Instance(this, "compute", {
      ami: "ami-123456",
      instanceType: "t3.micro",
      tags: { Name: "cdktf-instance" }
    });
  }
}

const app = new App();
new MyStack(app, "my-stack");
app.synth();

Your code "synthesized" into Terraform JSON, which Terraform would then execute. You got classes, loops, type checking—the whole nine yards. Sounds great, right?

Yeah, about that.

What Actually Happened

December 10, 2025: HashiCorp deprecated CDKTF. Same day: they archived the GitHub repo.

No warning, no migration window, no "we'll support critical bugs for another year." Just archived. The repository is now read-only. No updates, no bug fixes, no security patches. Ever.

Their official reason? "CDKTF did not find product-market fit at scale."

Translation: nobody used it.

And honestly? They're not wrong. Despite launching in 2020, CDKTF never caught on. Most Terraform users stuck with HCL. The ones who wanted "infrastructure as real code" went to Pulumi, which was already established and frankly better at it.

HashiCorp was maintaining language bindings for five different languages (TypeScript, Python, Go, C#, Java), updating providers, and keeping everything in sync—all for a tiny user base. At some point, you cut your losses.

Why Did CDKTF Fail?

Let me be blunt: CDKTF was always a weird compromise that nobody asked for.

The Impedance Mismatch

Terraform is declarative. You describe what you want, and Terraform figures out how to get there. That's its entire value proposition.

CDKTF tried to jam imperative programming into this declarative model. You'd write loops and conditionals in TypeScript, but they ran at synthesis time, not Terraform runtime. Try explaining that to someone debugging why their for loop isn't behaving like they expect.

// This looks imperative but it's not really
const instanceCount = process.env.PRODUCTION === "true" ? 10 : 2;

for (let i = 0; i < instanceCount; i++) {
  new Instance(this, `server-${i}`, {
    ami: "ami-123456",
    instanceType: "t3.micro"
  });
}

When does this loop run? Before Terraform even starts. How does Terraform track state changes? Awkwardly. What happens when you need to debug? You're dealing with both TypeScript errors AND Terraform errors.

It was cognitive overhead without clear benefits.

Pulumi Already Won This Battle

If you genuinely want to write infrastructure in TypeScript or Python, Pulumi has been doing it better since 2017. Native language runtime, superior type safety, actual IDE autocomplete that works, and an ecosystem that doesn't feel like an afterthought.

CDKTF was playing catch-up in a race Pulumi had already won. Why learn CDKTF when Pulumi does the same thing but better?

HashiCorp's Real Priority

HashiCorp is all-in on HCP Terraform (their cloud platform). They're pushing Terraform Cloud, Enterprise features, policy-as-code with Sentinel—basically, getting you into their ecosystem and keeping you there.

CDKTF didn't fit that strategy. It was a distraction. So they killed it.

Your Migration Options

Alright, enough doom and gloom. If you're running CDKTF in production, you have three real options and one fake option.

Option 1: Go Back to Terraform HCL

This is the obvious path. Rewrite your CDKTF code as regular Terraform HCL.

Good news: HashiCorp actually gave you a migration tool before they bailed. Run this:

cdktf synth --hcl

This generates standard Terraform HCL files from your CDKTF code. It's not perfect—you'll need to clean up and refactor—but it gives you a solid starting point instead of rewriting everything from scratch.

Here's what the migration looks like:

// CDKTF
new Instance(this, "web", {
  ami: "ami-123456",
  instanceType: "t3.micro",
  tags: { Name: "web-server" }
});
# Terraform HCL (after synth and cleanup)
resource "aws_instance" "web" {
  ami           = "ami-123456"
  instance_type = "t3.micro"

  tags = {
    Name = "web-server"
  }
}

Yeah, you'll still need to refactor the generated HCL. But at least you're not starting from zero.

Pros: you stay in the Terraform ecosystem, get official HashiCorp support, and tap into 100,000+ community modules.

Cons: you lose the programming language features you probably liked about CDKTF in the first place.

Option 2: Jump Ship to Pulumi

If you chose CDKTF because you wanted TypeScript/Python for infrastructure, Pulumi is the answer you should have picked from the start.

// Pulumi (TypeScript)
import * as aws from "@pulumi/aws";

const web = new aws.ec2.Instance("web", {
  ami: "ami-123456",
  instanceType: "t3.micro",
  tags: { Name: "web-server" }
});

export const publicIp = web.publicIp;

Pulumi feels like actual code because it is actual code. Real loops, real conditionals, real type checking—not synthesis-time pretend programming.

The migration effort is comparable to moving to HCL, but you end up in a better place if programming language features matter to you.

Downside: you're leaving the Terraform ecosystem entirely. Different state management, different tooling, different pricing model (Pulumi Cloud has tiers).

Option 3: AWS CDK (If You're AWS-Only)

If your infrastructure is entirely AWS and you were using CDKTF mainly because it felt like AWS CDK, HashiCorp actually recommends migrating to actual AWS CDK.

AWS CDK is AWS's own "infrastructure as code" tool using TypeScript/Python. It's AWS-native, well-supported, and not going anywhere.

Only makes sense if:

  • You're 100% AWS (no GCP, Azure, other providers)
  • You were already using AWS CDK constructs with CDKTF
  • You're willing to commit to AWS-only infrastructure

Not relevant for most multi-cloud setups, but worth mentioning since HashiCorp specifically called it out.

You could just... keep using CDKTF. Your code will work fine. For now.

But here's what's going to break eventually:

  • New Terraform providers won't have CDKTF bindings
  • Existing providers will update and break compatibility (no CDKTF updates to fix it)
  • Security vulnerabilities won't get patched
  • Node.js/Python/Go versions will march forward and break dependencies
  • Cloud provider APIs will change

Your infrastructure is on a ticking clock. Don't be the person who ignores it until 2 AM when prod is down.

How to Actually Migrate

Pick your poison (HCL or Pulumi), then follow this rough plan:

Week 1-2: Audit everything

Run cdktf list and cdktf synth to see what you actually have. Count your stacks, resources, dependencies. Be honest about complexity.

Week 3-4: Start small

Pick your simplest stack—maybe IAM roles or a single S3 bucket.

If going to HCL: run cdktf synth --hcl on that stack, clean up the output, then deploy to a test environment.

If going to Pulumi: rewrite it in Pulumi. Deploy to a test environment.

Break things. Learn.

Week 5-8: Import your existing resources

This is the tedious part. You need to import your existing infrastructure into Terraform state (or Pulumi state).

For Terraform:

terraform import aws_instance.web i-1234567890abcdef0
terraform plan  # Should show "No changes"

For Pulumi:

pulumi import aws:ec2/instance:Instance web i-1234567890abcdef0
pulumi preview  # Should show no changes

Week 9-16: Test, validate, cutover

Test in staging. Test again. Schedule a maintenance window. Import production resources. Validate. Decommission CDKTF.

Week 17-20: Clean up

Archive (don't delete) your CDKTF code. Update docs. Train your team. Remove CDKTF from CI/CD.

Handling the Tricky Bits

If you used CDKTF's dynamic features heavily, here's how they map:

Loops:

CDKTF:

for (let i = 0; i < 5; i++) {
  new Instance(this, `server-${i}`, { ... });
}

HCL:

resource "aws_instance" "server" {
  count = 5
  ami   = "ami-123456"
  # ...
  tags = { Name = "server-${count.index}" }
}

Pulumi (actually just use a real loop):

const instances = [];
for (let i = 0; i < 5; i++) {
  instances.push(new aws.ec2.Instance(`server-${i}`, {
    ami: "ami-123456",
    instanceType: "t3.micro"
  }));
}

Stack dependencies:

CDKTF let you reference other stacks directly. HCL uses remote state data sources. Pulumi uses stack references. Both work fine, just different syntax.

FAQs Nobody Asked But Should

Q: Can I use CDKTF for new projects?

No. Are you insane?

Q: Will my CDKTF code break immediately?

No, but eventually yes. Could be next month when a provider updates. Could be next year when your Node.js version changes. Could be tomorrow when AWS changes an API. You're gambling.

Q: Is there a converter tool?

Yes, actually. cdktf synth --hcl generates Terraform HCL from your CDKTF code. The output needs cleanup and refactoring, but it's way better than manual rewriting. Use it.

Q: What about cdk8s (CDK for Kubernetes)?

Different project, still alive. Only CDKTF is dead.

Q: HCL or Pulumi?

HCL if you want to stay in Terraform's ecosystem and don't mind learning a new syntax. Pulumi if you genuinely value programming language features and are willing to switch tools entirely. Both are fine choices.

The Lesson Here

CDKTF's death teaches us something important: sometimes "use your favorite language" isn't the answer.

HCL exists for a reason. It's constrained because infrastructure needs constraints. You can't accidentally write an infinite loop. State management is predictable. Resource relationships are explicit. Terraform can analyze and optimize the dependency graph.

Trying to bolt object-oriented programming onto a declarative infrastructure tool created more problems than it solved. The extra abstraction layer added complexity without enough benefits to justify itself.

If you want TypeScript for infrastructure, use Pulumi—it's designed that way from the ground up. If you want Terraform, use HCL. Trying to have both was the mistake.

What You Should Do Right Now

If you have CDKTF in production:

  1. Inventory your infrastructure (how bad is it?)
  2. Pick your migration target (HCL or Pulumi)
  3. Block out time on your calendar (this won't happen automatically)
  4. Start migrating non-critical stuff first
  5. Set a deadline (3-6 months is reasonable for most setups)
  6. Actually do it (don't put this off)

CDKTF is already archived. No support, no updates, no patches. Every day you wait is another day closer to something breaking in production at 3 AM.

Don't be that team.

Resources

Official stuff:

Analysis and hot takes:

If you're going the HCL route:

If you're going to Pulumi:


Look, I get it. You chose CDKTF because it seemed like the best of both worlds. TypeScript with Terraform's ecosystem. That was a reasonable bet in 2023.

But HashiCorp killed it, and now you need to move on. Pick a path, make a plan, and start executing. Future you will thank present you for not procrastinating on this.

Good luck.


Updated: 2025-12-30

Disclaimer: This is my analysis based on public info and community discussions. Check the official CDKTF repo for official details.