Представьте, что вы описываете нужные вам облачные ресурсы — корзину для файлов, базу данных, функцию — не галочками в консоли и не длинным YAML-файлом, а обычным кодом на том языке, который вы уже знаете. Создали объект «бакет» — получили бакет. Это и есть AWS CDK: способ описывать инфраструктуру как программу.
CDK не заменяет привычные инструменты, а надстраивается над ними. Под капотом всё равно работает CloudFormation — родной для AWS движок развёртывания. CDK лишь даёт вам писать поверх него на нормальном языке вместо ручной верстки шаблонов. Если слова «инфраструктура как код» пока звучат абстрактно, загляните в основы инфраструктуры как кода, а сюда возвращайтесь за конкретикой про CDK.
Что такое CDK
CDK (Cloud Development Kit, «набор для разработки облака») — это фреймворк, который позволяет описывать облачную инфраструктуру кодом на привычном языке программирования. Вы пишете программу, запускаете её, и на выходе получаете готовые ресурсы в AWS.
Ключевая идея в двух словах: CDK ничего не разворачивает напрямую. Он берёт ваш код, превращает его в обычный CloudFormation-шаблон (это называется «синтез»), а затем отдаёт этот шаблон CloudFormation, который уже создаёт и обновляет ресурсы. То есть собственного движка развёртывания у CDK нет — движок это CloudFormation. CDK — удобная надстройка перед ним.
Зачем это нужно, если можно писать CloudFormation вручную? Потому что код даёт то, чего нет у статичного шаблона:
- циклы и условия — создать десять одинаковых очередей в цикле, а не копировать блок десять раз;
- переменные и функции — вынести повторяющийся кусок в функцию;
- автодополнение и проверку типов в редакторе — опечатку видно сразу, а не при развёртывании;
- готовые библиотеки — целый набор сервисов «из коробки» с разумными настройками.
Главная библиотека называется aws-cdk-lib — это вторая версия CDK (v2), в неё собраны все сервисы AWS в одном пакете. Отдельно идёт пакет constructs — базовый строительный материал, о котором ниже.
Конструкты: L1, L2, L3
Конструкт (construct) — это базовый кирпичик CDK. Любой элемент инфраструктуры, который вы описываете, — это конструкт: бакет, база данных, целая сеть. Конструкты вкладываются друг в друга, и из мелких собираются крупные.
Конструкты делятся на три уровня по степени «удобности». Хорошая аналогия — сборка мебели:
L1 — «отдельные доски и саморезы». Это конструкты с приставкой Cfn в имени (например CfnBucket). Каждый L1 один-к-одному повторяет ресурс CloudFormation: все поля те же, ничего не упрощено, разумных значений по умолчанию нет — вы задаёте всё сами. Это самый низкий уровень, к нему спускаются редко, когда нужного свойства нет на уровнях выше.
new s3.CfnBucket(this, 'RawBucket', {
versioningConfiguration: { status: 'Enabled' },
});
L2 — «готовый шкаф с инструкцией». Это «причёсанные» конструкты с удобными настройками по умолчанию и понятными методами. Тот же бакет на уровне L2 — это просто s3.Bucket: он сам выставит безопасные настройки, а лишние детали скроет. Включить версионирование — один параметр.
new s3.Bucket(this, 'AppBucket', {
versioned: true,
});
L3 — «готовая комната под ключ». Это паттерны: композиции из нескольких L2-конструктов, решающие типовую задачу целиком. Один L3-конструкт может развернуть сразу контейнерный сервис вместе с балансировщиком нагрузки, сетью и правами доступа — то, что вручную заняло бы десятки строк.
Правило для новичка простое: по умолчанию берите L2. Они закрывают большинство задач. К L1 спускайтесь только за редкой настройкой, а L3 берите, когда узнаёте в нём ровно свою задачу.
App и Stack
У описания на CDK есть строгая иерархия из трёх уровней вложенности — её удобно держать в голове как «папки».
- App — корень всего, само приложение CDK. Это та точка, с которой запускается синтез. App ничего не разворачивает сам — он лишь контейнер для стеков.
- Stack — стек. Это и есть единица развёртывания: один Stack превращается ровно в один CloudFormation-стек. Внутри одного App может быть несколько Stack — например, отдельно сеть, отдельно база, отдельно приложение.
- Конструкты — кирпичики (L1/L2/L3) лежат внутри Stack.
Получается дерево: App → Stack → конструкты. Свой стек вы описываете как класс, наследующий Stack, а ресурсы создаёте в его конструкторе.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class AppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'AppBucket', { versioned: true });
}
}
Точка входа — это файл, где создаётся App и в него добавляются стеки:
import * as cdk from 'aws-cdk-lib';
import { AppStack } from './app-stack';
const app = new cdk.App();
new AppStack(app, 'AppStack');
app.synth();
Обратите внимание на три аргумента у каждого конструкта: scope (родитель — где он живёт), id (имя внутри родителя) и свойства. Из пары «родитель + id» CDK строит уникальный путь до каждого ресурса в дереве.
Как CDK превращается в CloudFormation
Здесь полезно увидеть весь путь от кода до работающих ресурсов по шагам. Команды запускаются через CLI-инструмент cdk.
Шаг 0 — cdk bootstrap (один раз на аккаунт и регион). Готовит вспомогательные ресурсы, которые CDK нужны для работы: бакет для артефактов, права доступа. Делается единожды.
cdk bootstrap
Шаг 1 — cdk synth (синтез). Запускает вашу программу и генерирует из неё CloudFormation-шаблон. Это и есть та самая «компиляция» кода в шаблон. Шаблон можно открыть и прочитать глазами — полезно, чтобы понять, что именно создастся.
cdk synth
Шаг 2 — cdk diff (что изменится). Сравнивает то, что описано в коде, с тем, что уже развёрнуто, и показывает разницу: какие ресурсы добавятся, изменятся или удалятся. Привычка смотреть diff перед развёртыванием спасает от случайных правок.
cdk diff
Шаг 3 — cdk deploy (развёртывание). Отдаёт шаблон CloudFormation, и тот создаёт или обновляет ресурсы. Развёртыванием по-прежнему занимается CloudFormation — со всеми его свойствами: откатом при ошибке, отслеживанием состояния, безопасным обновлением.
cdk deploy
Удалить всё созданное стеком можно командой cdk destroy. А связать эти команды в автоматический конвейер — задача отдельная, про неё стоит почитать в принципах CI/CD-конвейеров.
На каких языках пишут
Важный момент, который часто понимают неправильно: у CDK нет «главного» языка. Он поддерживает несколько языков, и все они равноправны:
- TypeScript (и JavaScript)
- Python
- Java
- Go
- C#
Это не «обёртки разного качества». Под капотом CDK использует технологию, которая транслирует одну и ту же библиотеку во все эти языки автоматически, поэтому набор конструктов, их свойства и поведение одинаковы везде. Выбирайте тот язык, на котором уже пишет ваша команда, — так инфраструктура живёт рядом с остальным кодом, в одном репозитории и с одними привычками.
Примеры в этой статье на TypeScript просто потому, что это самый частый выбор для документации и обучения, а не потому, что он «правильный». Тот же бакет на Python выглядит так же по смыслу:
from aws_cdk import Stack, aws_s3 as s3
from constructs import Construct
class AppStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
s3.Bucket(self, "AppBucket", versioned=True)
Создать новый проект на нужном языке помогает команда cdk init с флагом --language (typescript, python, java, go, csharp).
cdk init app --language=python
Где это применяется
CDK выбирают там, где инфраструктуры много и она меняется часто, а команда уже живёт в мире кода: те же редакторы, те же отзывы на изменения, тот же репозиторий. Особенно удобно, когда инфраструктура повторяется — несколько одинаковых окружений или десяток однотипных сервисов: цикл и функция убирают копирование, которого в статичном шаблоне не избежать.
Типичные ошибки новичков:
- Думать, что CDK сам разворачивает ресурсы. Нет — он синтезирует CloudFormation-шаблон, а разворачивает CloudFormation. Все ограничения и поведение наследуются от него.
- Сразу лезть на уровень L1.
Cfn-конструкты многословны и без значений по умолчанию. Начинайте с L2 и спускайтесь ниже только при реальной необходимости. - Развёртывать без
cdk diff. Без взгляда на разницу легко удалить ресурс, который не собирались трогать. - Забывать про
cdk bootstrap. Первое развёртывание в новом аккаунте или регионе без него просто не пройдёт. - Менять созданные CDK ресурсы руками в консоли. Тогда код и реальность расходятся, и следующий
deployведёт себя непредсказуемо. Источник правды — код.
Куда двигаться дальше. Полезно понять сам CloudFormation — раз CDK строит шаблоны для него, знание основы убирает магию. Рядом стоит посмотреть на Terraform — другой подход к той же задаче, чтобы понимать, из чего выбирают. Тему состояния и доставки инфраструктуры стоит освоить, когда дойдёте до командной работы: где хранится состояние, как раскатывать изменения безопасно. А чтобы понимать, какими ресурсами вы вообще управляете, держите под рукой основы AWS, сеть и права доступа IAM — без понимания самих сервисов любой инструмент управления ими остаётся набором заклинаний.