DEV Community

Alex Spinov
Alex Spinov

Posted on

CDKTF Has Free Terraform in TypeScript — Here's How to Ditch HCL Forever

Love Terraform but hate HCL? CDKTF lets you write Terraform configs in TypeScript, Python, Java, C#, or Go.

What is CDKTF?

CDK for Terraform (CDKTF) is an open-source project by HashiCorp that lets you define Terraform infrastructure using programming languages instead of HCL.

Quick Start

npm install -g cdktf-cli
cdktf init --template=typescript --providers=aws
Enter fullscreen mode Exit fullscreen mode

Your First CDKTF Stack

import { Construct } from "constructs";
import { App, TerraformStack, TerraformOutput } from "cdktf";
import { AwsProvider } from "@cdktf/provider-aws/lib/provider";
import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket";
import { Instance } from "@cdktf/provider-aws/lib/instance";

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

    new AwsProvider(this, "aws", { region: "us-east-1" });

    // S3 Bucket
    const bucket = new S3Bucket(this, "app-bucket", {
      bucket: "my-app-assets-2026",
      tags: { Environment: "production" },
    });

    // EC2 Instance
    const server = new Instance(this, "web-server", {
      ami: "ami-0c02fb55956c7d316",
      instanceType: "t3.micro",
      tags: { Name: "WebServer" },
    });

    new TerraformOutput(this, "bucket-name", { value: bucket.bucket });
    new TerraformOutput(this, "server-ip", { value: server.publicIp });
  }
}

const app = new App();
new MyStack(app, "my-infra");
app.synth();
Enter fullscreen mode Exit fullscreen mode
cdktf deploy
Enter fullscreen mode Exit fullscreen mode

Loops and Conditions (Why CDKTF Wins)

// Create 3 identical servers with a loop
const serverNames = ["web-1", "web-2", "web-3"];
serverNames.forEach(name => {
  new Instance(this, name, {
    ami: "ami-0c02fb55956c7d316",
    instanceType: "t3.micro",
    tags: { Name: name },
  });
});

// Conditional resources
if (isProduction) {
  new Instance(this, "monitoring", {
    instanceType: "t3.large",
    // ...
  });
}
Enter fullscreen mode Exit fullscreen mode

In HCL you would need count, for_each, and conditional expressions. In CDKTF — just use TypeScript.

Reusable Constructs

class WebApp extends Construct {
  public readonly url: string;

  constructor(scope: Construct, id: string, props: { domain: string; size: string }) {
    super(scope, id);

    const bucket = new S3Bucket(this, "assets", {
      bucket: `${props.domain}-assets`,
    });

    const server = new Instance(this, "server", {
      instanceType: props.size,
      ami: "ami-0c02fb55956c7d316",
    });

    this.url = server.publicDns;
  }
}

// Use it
const app1 = new WebApp(this, "app1", { domain: "example.com", size: "t3.micro" });
const app2 = new WebApp(this, "app2", { domain: "staging.example.com", size: "t3.small" });
Enter fullscreen mode Exit fullscreen mode

CDKTF vs Pulumi vs HCL Terraform

Feature CDKTF Pulumi HCL Terraform
Languages TS, Python, Go, Java, C# TS, Python, Go, C# HCL
State Backend Terraform (S3, Cloud) Pulumi Cloud, S3 S3, Cloud
Provider Ecosystem All Terraform providers Most TF providers All native
Existing TF Code Import directly Convert needed Native
Testing Jest/Vitest Built-in Terratest

Key Advantage: Full Terraform Ecosystem

CDKTF generates standard Terraform JSON. This means every Terraform provider, every module, every backend — it all works. You get TypeScript DX with Terraform reliability.


Need managed infrastructure for data extraction? Check out my Apify actors — no infrastructure management needed. For custom solutions, email spinov001@gmail.com.

Top comments (0)