linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/kb/Advanced/tf-cdktf

kb/advanced ── Advanced ── advanced

CDKTF, Terraform на TypeScript/Python

CDKTF, Terraform на TypeScript/Python/Go/Java/C#. На выходе стандартный HCL + tfstate. Плюсы: типы, autocomplete, циклы и классы. Минусы: ещё одна абстракция, debug сложнее, не все фичи Terraform покрыты 1:1. Оправдан когда нужна программируемая генерация HCL (N stack'ов из CSV, например).

view as markdownaka: cdktf, cdk-terraform, cdktf-typescript, cdktf-python

Что это

CDKTF, генератор HCL из кода. Пишешь на одном из языков:

  • TypeScript / JavaScript (основной)
  • Python
  • Java
  • C#
  • Go

Запускаешь cdktf synth, на выходе папка cdktf.out/stacks/<stack>/ с обычным HCL (cdk.tf.json). Дальше, terraform init && plan как обычно (или cdktf deploy, который делает то же самое из CDKTF).

Идея, Terraform-провайдеры остаются те же, state остаётся terraform-state, но HCL пишется кодом.

Минимальный пример (TypeScript)

bash
cdktf init --template=typescript --local

Генерится main.ts:

typescript
import { App, TerraformStack } from "cdktf";
import { Construct } from "constructs";
import { AwsProvider } from "./.gen/providers/aws/provider";
import { S3Bucket } from "./.gen/providers/aws/s3-bucket";
class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);
    new AwsProvider(this, "aws", { region: "us-east-1" });
    new S3Bucket(this, "logs", {
      bucket: "linuxlab-cdktf-logs",
      tags: { ManagedBy: "cdktf" },
    });
  }
}
const app = new App();
new MyStack(app, "main");
app.synth();

Запуск:

bash
cdktf get          # подтягивает type-bindings для провайдеров
cdktf synth        # генерит HCL в cdktf.out/
cdktf deploy main  # apply

Что синтезируется

cdktf.out/stacks/main/cdk.tf.json:

json
{
  "terraform": {
    "required_providers": {"aws": {...}}
  },
  "provider": {
    "aws": [{"region": "us-east-1"}]
  },
  "resource": {
    "aws_s3_bucket": {
      "logs": {
        "bucket": "linuxlab-cdktf-logs",
        "tags": {"ManagedBy": "cdktf"}
      }
    }
  }
}

Это обычный JSON-HCL. Никаких CDKTF-специфик в облаке.

Когда CDKTF оправдан

Программируемая генерация

100 одинаковых stack'ов из CSV:

typescript
const tenants = require("./tenants.json");
tenants.forEach((tenant: any) => {
  new TenantStack(app, `tenant-${tenant.id}`, {
    name: tenant.name,
    tier: tenant.tier,
  });
});

В HCL это была бы куча terraform.tfvars или for_each, но без типов и без if'ов на бизнес-логике.

Сложная условная логика

typescript
if (config.env === "prod" && config.region.startsWith("eu-")) {
  new GDPRComplianceModule(this, "gdpr", { ... });
}

В HCL, count = ... ? 1 : 0 с кучей условий. На TypeScript, читается.

Переиспользование через классы

typescript
class AuditedBucket extends Construct {
  constructor(scope: Construct, name: string, props: AuditedBucketProps) {
    super(scope, name);
    new S3Bucket(this, "bucket", { /* ... */ });
    new S3BucketVersioningA(this, "versioning", { /* ... */ });
    new S3BucketPublicAccessBlock(this, "pab", { /* ... */ });
  }
}
new AuditedBucket(this, "logs", { name: "audit-logs" });

Это аналог Terraform-модуля, но с типами и наследованием.

Когда CDKTF, НЕ оправдан

Маленький проект

Один stack, 50 ресурсов, без сложной логики, нативный HCL понятнее и короче. CDKTF добавляет step'ы (init, get, synth, deploy) и build-зависимости (node_modules, 500 MB+).

Команда не знает TypeScript/Python

Reviewer ревьюит и HCL, и TypeScript. Если последнего никто не знает плохая идея. Reviewing 200-line .ts сложнее, чем .tf.

Хочешь использовать community-modules

Большинство Terraform Registry modules написаны на HCL. Использовать их из CDKTF можно (TerraformHclModule), но workflow менее естественный.

Структура проекта

my-cdktf/
├── main.ts                 # entrypoint
├── stacks/
│   ├── network.ts
│   ├── compute.ts
│   └── data.ts
├── constructs/
│   ├── audited-bucket.ts
│   └── vpc-with-flow-logs.ts
├── cdktf.json              # язык, providers, build
├── package.json
└── cdktf.out/              # generated HCL (gitignore)

В cdktf.json:

json
{
  "language": "typescript",
  "app": "npx ts-node main.ts",
  "terraformProviders": ["aws@~> 5.60", "random@~> 3.6"],
  "terraformModules": [],
  "context": {}
}

Tests

Тесты, обычные Jest/pytest. CDKTF предоставляет helpers:

typescript
import { Testing } from "cdktf";
test("bucket has correct name", () => {
  const synth = Testing.synthScope((scope) => {
    new MyStack(scope, "test");
  });
  expect(synth).toHaveResourceWithProperties(S3Bucket, {
    bucket: "linuxlab-cdktf-logs",
  });
});

Это assertion на сгенерированный JSON. Быстро, никакого облака.

Подводные камни

  • cdktf get нужен после смены провайдеров. Type-bindings генерятся локально; добавил новый provider в cdktf.json → cdktf get. Без него TypeScript не видит типы.

  • node_modules/ тяжёлый. 500-1500 MB на средний проект. В Docker билде CI медленный без npm ci --omit=dev.

  • HCL-generated читать тяжело. Синтезированный JSON неотформатирован под человека; debug через cdktf synth && cat cdktf.out/.../cdk.tf.json | jq, не самый приятный.

  • State files те же. CDKTF не создаёт собственный state; использует terraform.tfstate. Это плюс (миграция назад в HCL возможна), но означает что remote backend настраивается так же.

  • Terraform-фичи не на 1:1. moved / removed / import блоки в CDKTF поддерживаются, но менее идиоматично. Сложные dynamic блоки могут потребовать escapeHatch.

  • Не путать с AWS CDK. AWS CDK генерит CloudFormation; CDKTF генерит Terraform. Похожий синтаксис, разный backend.

  • Performance: cdktf synth на больших проектах, секунды-минуты. На каждом CI-run перегенерация. Для 1000+ ресурсов делается кэширование generated-HCL.

§ команды

bash
cdktf init --template=typescript --local

Скелет проекта на TypeScript с local-backend.

bash
cdktf get

Подтянуть type-bindings для провайдеров из cdktf.json.

bash
cdktf synth

Сгенерировать HCL в cdktf.out/. Не делает apply.

bash
cdktf deploy

synth + terraform apply одной командой.

bash
cdktf diff

synth + terraform plan.

§ см. также

  • tf-terragruntTerragrunt, DRY-обёртка над TerraformTerragrunt, обёртка Gruntwork, решает проблему «directory-per-env» дублирования. Объявляешь `terragrunt.hcl` с `inputs` и `include`'ами; Terragrunt генерирует backend.tf, provider.tf и main.tf на лету и вызывает `terraform`. Альтернатива, workspaces (опасно), copy-paste (плохо), CDKTF (другой стек). Стоимость, ещё один tool в цепочке, ещё один HCL-диалект.
  • tf-provider-developmentСвой Terraform-провайдер, Plugin FrameworkСвой provider, Go через terraform-plugin-framework. Модель: Provider → Resource (CRUD) или DataSource (R). Каждый ресурс, Schema + методы Create/Read/Update/Delete. Core общается с provider по gRPC. Деплой: `go install` + dev_overrides, или Terraform Registry. Нужен когда нет готового provider для твоего API.
  • tf-stacksTerraform Stacks, нативная multi-stack оркестрацияTerraform Stacks, фича HCP Terraform (2024), частично закрывает то что делал Terragrunt. Один stack = множество components, между ними явные dependencies, deployment с разными inputs делает развёртывание N сред из одной конфигурации. Сейчас Cloud-only (HCP Terraform), open-source CLI, в работе. Кому нужно сегодня: либо HCP Terraform, либо ждать, либо использовать Terragrunt.
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.