2023年Terraform开源协议变更时,开发者社区一片哀嚎。但很少有人注意到,HashiCorp同期放出了一个"逃生舱"——CDK for Terraform(CDKTF)。这个工具让你用TypeScript、Python、Java、C#或Go写基础设施代码,彻底告别HCL的括号地狱。
两年过去,CDKTF的GitHub Star数突破1.2万,npm周下载量稳定在4万次以上。更关键的是,它完全免费,且不受Terraform商业协议限制。
从HCL到TypeScript:一场语法层面的"降维打击"
HCL的问题从来不是"不能跑",而是"写起来像在做填空题"。你需要记住count、for_each、dynamic block的诡异语法,调试时盯着一堆${}嵌套怀疑人生。
CDKTF的做法很直接:把基础设施变成真正的代码。
安装只需要两行命令:
npm install -g cdktf-cli
cdktf init --template=typescript --providers=aws
然后你就能用熟悉的面向对象思维定义资源。创建一个S3桶加EC2实例,代码结构和普通Node.js项目没区别:
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" });
const bucket = new S3Bucket(this, "app-bucket", {
bucket: "my-app-assets-2026",
tags: { Environment: "production" },
});
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();
cdktf deploy
执行cdktf deploy后,CDKTF会先把TypeScript编译成标准的Terraform JSON配置,再调用terraform apply。你的团队可以逐步迁移,不需要一次性重写所有HCL。
循环、条件、复用:这才是程序员该有的工具
HCL的count和for_each能解决问题,但代价是心智负担。CDKTF直接让你用原生语言特性:
// 创建3台服务器
const serverNames = ["web-1", "web-2", "web-3"];
serverNames.forEach(name => {
new Instance(this, name, {
ami: "ami-0c02fb55956c7d316",
instanceType: "t3.micro",
tags: { Name: name },
});
});
// 条件资源
if (isProduction) {
new Instance(this, "monitoring", {
instanceType: "t3.large",
});
}
更实用的是Construct机制。你可以把常用资源组合封装成可复用的类,像搭积木一样构建基础设施:
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;
}
}
// 实例化两个环境
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" });
这种抽象能力在HCL里需要借助模块(module)实现,但模块的输入输出定义繁琐,且无法像类一样携带方法和状态。
CDKTF、Pulumi、HCL:三选一怎么挑
CDKTF不是唯一的选择。Pulumi更早支持多语言基础设施,且原生设计就是"代码优先";Terraform本身的HCL也在进化,1.5版本加入了可选的类型约束和测试框架。
三者的核心差异在于:
Pulumi:自研引擎,不依赖Terraform生态。优势是执行速度快、状态管理更灵活;劣势是Provider覆盖率不如Terraform,且商业版定价对团队规模敏感。
CDKTF:站在Terraform肩膀上,所有Provider和模块直接复用。适合已经深度使用Terraform、但想逃离HCL的团队。免费,且因为生成的是标准Terraform配置,可以和其他工具链无缝衔接。
HCL Terraform:生态最成熟,IDE支持最好。但语法天花板明显,复杂逻辑写起来像"用Excel做数据库"。
一个常被忽略的细节:CDKTF生成的JSON配置可以git diff,而Pulumi的状态变更对团队来说更"黑盒"。对于需要严格审计的基础设施变更,这是关键考量。
谁该现在上车
CDKTF的维护团队HashiCorp被IBM收购后,项目归属一度引发担忧。但2024年底的社区公告显示,CDKTF已转入社区驱动模式,核心贡献者包括AWS、Google Cloud的工程师。
目前最活跃的场景有三类:一是已有TypeScript/Python技术栈的Web团队,不想为基础设施单独维护一套HCL;二是需要复杂条件判断和循环的多环境部署;三是想把基础设施代码和应用程序代码放在同一个仓库、用同一套CI/CD流程管理。
一个Reddit用户的反馈很典型:「我们花了两周把2000行HCL重构成TypeScript,代码量降到800行,而且新来的后端工程师第一天就能看懂基础设施逻辑。」
但CDKTF也有代价。调试时需要同时理解生成的Terraform配置和原始TypeScript,错误堆栈偶尔让人困惑。另外,cdktf-cli的版本和Terraform版本存在兼容矩阵,升级时需要两头对齐。
如果你的团队正在Terraform和Pulumi之间犹豫,CDKTF提供了一个中间选项:不换引擎,只换语法。毕竟,基础设施代码也是代码,程序员值得用程序员的方式写。
你现在的Terraform代码库里,最让你想砸键盘的HCL片段长什么样?
热门跟贴