ADG Оставить заявку
Блог DevOps 4 мин чтения

CDKTF 0.11 и Python: пишем IaC без HCL на реальном примере Proxmox-провайдера

Terraform CDK 0.11 стабилизировал Python-привязки - тестируем CDKTF как альтернативу HCL для команд с Python-бэкграундом на примере модуля для Proxmox.

Контекст момента

Terraform CDK (CDKTF) 0.11 (июнь 2022): стабилизация TypeScript/Python провайдеров, улучшенный CLI workflow

Terraform CDK, он же CDKTF, развивается уже больше года, но в релизе 0.11 что-то щёлкнуло - Python-провайдеры наконец перестали быть экспериментом на бумаге и стали чем-то, что можно брать на пилот. Мы и взяли.

Контекст такой: часть наших клиентов переходит на Proxmox как основную платформу виртуализации. IaC для Proxmox через Terraform и провайдер Telmate/proxmox - это HCL, который работает, но требует освоения синтаксиса. У части команд бэкграунд чисто Python, и HCL для них - ещё один язык, который нужно выучить. Логичный вопрос: зачем, если можно писать инфраструктуру на Python?

Что изменилось в CDKTF 0.11

До 0.11 генерация Python-привязок для провайдеров работала нестабильно: часть атрибутов терялась, типизация была частичной, CLI мог упасть при синтезе сложного стека. Для небольших экспериментов - сойдёт, для реального использования - раздражает.

В 0.11 HashiCorp переработала механизм генерации привязок. Ключевые изменения по существу:

  • Генерация провайдеров через cdktf provider add стала надёжной: правильно обрабатываются вложенные блоки, списки, computed-атрибуты.
  • CLI workflow - cdktf synth, cdktf plan, cdktf deploy - работает предсказуемо и не теряет контекст между вызовами.
  • Размер пакетов уменьшился: провайдеры теперь разбиваются на отдельные модули, не нужно тащить всё целиком.

Это не значит, что всё идеально. CDKTF 0.11 - всё ещё пре-1.0. Но разница с 0.9-0.10 ощутима.

Структура пилота

Брали реальную задачу: описать типовую VM для application-сервера на Proxmox. То, что в HCL выглядит как 40 строк .tf-файла, мы хотели написать на Python с нормальными абстракциями - классом, дефолтами, переиспользованием.

Инициализация проекта:

cdktf init --template=python --local
cdktf provider add "telmate/proxmox@~>2.9.11"

cdktf provider add скачивает провайдер и генерирует Python-пакет с привязками. На Proxmox-провайдере генерация заняла около двух минут - провайдер нетривиальный по схеме.

Пример модуля

Вот упрощённая версия того, что получилось. Класс AppServerVM оборачивает ресурс ProxmoxVirtualMachine и задаёт дефолты для нашего типового профиля:

from constructs import Construct
from cdktf import TerraformStack
from cdktf_cdktf_provider_proxmox.virtual_machine import VirtualMachine, VirtualMachineDisk, VirtualMachineNetwork

class AppServerVM(Construct):
    def __init__(
        self,
        scope: Construct,
        id: str,
        *,
        node: str,
        hostname: str,
        cores: int = 4,
        memory: int = 4096,
        disk_size: str = "40G",
        vlan_id: int = 100,
        template: str = "almalinux-8-cloud",
    ):
        super().__init__(scope, id)

        VirtualMachine(
            self,
            "vm",
            name=hostname,
            target_node=node,
            clone=template,
            cores=cores,
            memory=memory,
            disk=[VirtualMachineDisk(
                size=disk_size,
                type="scsi",
                storage="local-lvm",
            )],
            network=[VirtualMachineNetwork(
                bridge="vmbr0",
                model="virtio",
                tag=vlan_id,
            )],
            os_type="cloud-init",
            ipconfig0=f"ip=dhcp",
        )

В стеке это используется так:

class InfraStack(TerraformStack):
    def __init__(self, scope: Construct, ns: str):
        super().__init__(scope, ns)

        # Провайдер
        ProxmoxProvider(self, "proxmox",
            pm_api_url="https://pve01.example.com:8006/api2/json",
            pm_api_token_id=os.environ["PM_TOKEN_ID"],
            pm_api_token_secret=os.environ["PM_TOKEN_SECRET"],
        )

        AppServerVM(self, "app-01",
            node="pve01",
            hostname="app-01.example.com",
            cores=8,
            memory=8192,
        )

        AppServerVM(self, "app-02",
            node="pve02",
            hostname="app-02.example.com",
        )  # дефолты 4 core / 4G

Это уже ближе к тому, как команды пишут Python-код: дефолты в сигнатуре, переиспользование через класс, читаемость без знания HCL.

Что реально сработало

Абстракции естественны. Python-класс с дефолтными аргументами - понятная модель для любого питониста. HCL-модули с переменными делают то же самое, но через другой синтаксис, который нужно изучать отдельно.

Тесты. Это главный аргумент. К Python-коду можно написать юнит-тесты через pytest. Мы проверяем, что стек синтезируется корректно, что все ресурсы присутствуют, что параметры передаются правильно. В HCL аналог - только сторонние инструменты вроде Terratest, и это отдельная боль.

Переиспользование через пакеты. Класс AppServerVM можно упаковать в Python-пакет и использовать в нескольких проектах. Версионирование - стандартный pyproject.toml.

Где пока трудно

Честно: не всё гладко.

Генерация под нестандартные провайдеры. Proxmox-провайдер Telmate - не первоклассный. Часть атрибутов в схеме объявлена нечётко, и генерация иногда даёт привязки с Any-типами вместо нормальных. Не критично, но теряется статическая типизация именно там, где провайдер написан небрежно.

cdktf synth медленный. Синтез стека - это выполнение Python и генерация JSON с ресурсами. На больших стеках это заметно. HCL terraform plan работает быстрее.

Отладка через синтезированный JSON. Когда что-то идёт не так на уровне Terraform (уже после синтеза), нужно смотреть в cdktf.out/ и читать сгенерированный HCL/JSON. Это дополнительный слой между кодом и ошибкой.

Вывод на сейчас

CDKTF 0.11 - рабочий инструмент для пилота. Не для всех и не для всего, но для команды с Python-бэкграундом, которая разворачивает типовую инфраструктуру на Proxmox или другой платформе с Terraform-провайдером, это реальная альтернатива изучению HCL.

Мы продолжаем пилот - задействуем тот же подход на втором клиенте с другим профилем инфраструктуры. Если паттерн подтвердится, будем включать CDKTF Python в стандартный инструментарий для managed-сопровождения проектов, где команда уже пишет на Python.

HCL никуда не денется - он остаётся основным путём для Terraform. Но то, что теперь есть вменяемая альтернатива для определённого профиля команд, - это хорошая новость.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.