AWS — лидер на рынке облачной инфраструктуры. Amazon предоставляет широкий спектр сервисов для построений облачных систем. Однако порог входа довольно высокий.
Георгий Андрончик, архитектор Almus с восьмилетним опытом в индустрии и соавтор курса «Профессия Архитектор ПО», демонстрирует мощь aws cdk. Текст будет интересен программистам, которые уже работают с AWS или имеют желание с ним познакомиться.
AWS Cloud Development Kit — решение, которое позволяет определять ресурсы для облачных приложений, используя привычные языки программирования. При использовании CDK вы будете иметь дело с самой библиотекой и консольным клиентом.
Библиотека позволяет описывать инфраструктуру на привычных языках (Java, Javascript, Typescript, Python и C#). С помощью консольного клиента вы можете задеплоить или синтезировать свой код. Используя команду deploy, вы напрямую создаете ресурсы в AWS. Вы можете сделать это прямо с машины разработчика или сервера развертывания, такого как CodePipeline. Эта команда похожа на Terraform apply. Используя команду synth, вы можете синтезировать CloudFormation.
CDK создает конструкции внутри стеков. Они содержат ресурсы AWS, такие как SQS или Lambda. Далее CDK генерирует из этого CloudFormation JSON файл. И вы можете разворачивать эти темплейты с помощью CloudFormation.
CDK облегчает описание и развертывание инфраструктуры, позволяет переиспользовать constructs (абстракции композиций ресурсов AWS) без потери обратной совместимости с CloudFormation.
Какие выводы из этого можно сделать? AWS CDK снижает уровень входа, экономя ваши деньги как при создании mvp или proof of concept, так и при развитии вашего проекта. При этом вы ничем не рискуете и можете от него отказаться в любой момент и перейти на CloudFormation.
Теперь давайте посмотрим на этого зверя поближе. Напишем простой serverless api с использованием sqs, dynamoDB и lambda на языке typescript.
Настройка окружения
Я не буду рассказывать как зарегистрировать аккаунт aws и создать пользователя, для этого уже есть огромное количество материалов в сети.
Для начала работы нам потребуется установить AWS command line interface и aws cdk.
Для установки cli стоит прибегнуть к документации aws. Установить cdk также не должно составить труда, все подробно описано здесь.
Создаем первый стек
Создаем пустую директорию, где будет лежать наш проект, переходим в нее и создаем пустой стек при помощи команды cdk init.
Открываем сгенерированный проект и видим следующее:
В директории bin лежит запускной файл, содержащий следующий код:
Здесь мы создаем construct и передаем его в конструктор нашего первого стека.
В директории lib лежит сам стек:
В папке test соответственно находятся тесты. Файл cdk.json — конфиг cdk проекта. Его мы в рамках статьи трогать не будем и оставим дефолтным.
Переходим в файл package.json и прописываем необходимые нам зависимости:
"@aws-cdk/aws-sqs"
"@aws-cdk/aws-dynamodb"
"@aws-cdk/aws-lambda"
"@aws-cdk/aws-apigateway"
"@aws-cdk/aws-iam"
это пакеты для работы с созвучными сервисами aws
"@types/aws-lambda" в свою очередь поможет нам типизировать некоторые объекты.
Далее вызываем npm install для того, чтобы подтянуть наши зависимости.
Структура проекта
Следующим шагом зададим структуру нашего проекта.
Создадим каталог handlers, где будут лежать наши lambda функции. В нем создадим папки notify и subscribe и файлы main.ts в каждой. Также добавим папку models в корень нашего проекта. Тут будут лежать модели. Добавим туда файл order.ts.
Пишем код
В файл order.ts добавим следующий код:
Модель Order с двумя полями - id и датой создания. В файле handlers/notify/main.ts добавляем следующее:
Это наша lambda функция, которая будет вызываться при обращении к api. В теле функции мы создаем объект Order с рандомным id и текущим временем. Далее мы создаем объект params, который принимает как аргумент функция sendMessage экземпляра класса SQS. Params содержит QueueUrl — url нашей очереди, а также MessageBody — тело сообщения. После отправки сообщения мы возвращаем объект со статус-кодом 200 и телом с текстом о успешном добавлении order.
Открываем файл handlers/subscribe/main.ts и вставляем код:
Эта lambda будет слушать очередь, парсить сообщение в объект Order и писать в табличку DynamoDB.
Открывает файл ap-stack.ts и добавляем в конструктор следующий код:
Таким образом мы создаем очередь и табличку dynamoDB.
А вот так мы создаем функцию notify:
runtime — это среда в которой будет выполняться наша функция. В нашем случае это NodeJS 12. handler — имя файла и имя функции которая экспортируется в нем. code — путь к коду. environment — переменные которые мы прокидываем в функцию, в нашем случае это url нашей очереди.
Теперь создадим rest api и привяжем нашу lambda функцию к root get запросу.
Теперь давайте напишем функцию подписчика нашей очереди:
Тут все аналогично функции паблишера, за исключением параметра events.
Этот параметр содержит экземпляр SqsEventSource, который в свою очередь и будет подвязывать нашу функцию к созданной ранее очереди.
Все что нам осталось — это дать права нашим функциям:
Паблишеру — права на отправку сообщений в очередь, подписчику — права на добавление записей в базу данных.
Все готово, давайте задеплоим наше решение и протестим!
Деплоим и тестируем
Перед тем как залить наш код, давайте сбилдим javaScript из нашего typeScript. Для этого открываем телиман и пишем команду: npm run build
После пишем команду cdk deploy, ждем несколько минут и копируем api endpoint (AppStack.apiEndpoint), который видим в консоли.
Вставляем этот url в адресную строку браузера и видим следующее:
Это ответ функции notify о успешном добавлении order.
Далее идем в админку aws, пишем в строке поиска dynamoDB и переходим в соответствующий раздел:
Там выбираем нашу табличку и видим запись, которая только что была добавлена:
Заключение
Поздравляю, мы только что создали, задеплоили и протестировали serverless api с использованием ряда сервисов aws при помощи aws cdk. Достаточно просто и быстро не так ли?
Исходный код с примером из статьи вы можете найти здесь.
Фото: whiteMocca / Shutterstock
Нашли опечатку? Выделите текст и нажмите Ctrl + Enter