Начните работу с Serverless, Lambda и Docker
SAM - это фреймворк с открытым исходным кодом, который можно использовать для создания, тестирования и развертывания бессерверных приложений на AWS.
Основная цель этой статьи - познакомить вас с AWS SAM, чтобы вы могли тестировать свои лямбда-выражения на локальном компьютере без необходимости (повторно) развертывать их каждый раз на AWS. Я расскажу о различных интеграциях и примерах с SAM и лямбда.
SAM использует Docker для локального создания и запуска лямбда-выражений, поэтому необходимы базовые знания Docker.
Архитектура
Допустим, у компании много документов. В этих документах есть documentId
и versionId
. Также существует несколько версий одного документа.
Сотрудникам компании сложно найти конкретные версии документов. Компания разработала решение, позволяющее упростить запрос места хранения документа на основе его documentId
и versionId
.
Давайте переведем пример использования на техническую архитектуру в AWS. Мы будем использовать DynamoDB для хранения documentId
, versionId
и места хранения документа. Нам нужно заполнить таблицу DynamoDB информацией о существующем документе, а затем настроить интеграцию лямбда-прокси в API Gateway. Конечный пользователь сможет получить правильное место хранения документа, выполнив запрос GET с правильными параметрами (documentId
и versionId
) к конечной точке шлюза API.
Мы можем использовать SAM для развертывания этого стека в AWS, но одна из сильных сторон SAM заключается в том, что он предлагает простой способ локального тестирования ваших интеграций.
Мы будем использовать SAM local для:
- Вызов лямбда-выражения один раз с помощью SAM CLI для заполнения DynamoDB.
- Разместите нашу локальную конечную точку шлюза API с интеграцией лямбда-прокси.
- Создайте образец события, которое шлюз API отправляет нашей лямбда-функции, когда кто-то ищет документ.
Когда все будет работать локально, мы развернем полный стек в AWS.
Начальная настройка
Чтобы можно было следить за этой демонстрацией, вам потребуются следующие предварительные условия:
- Докер
- SAM CLI
- AWS CLI
- Демо-проект GitHub
- Аккаунт AWS (необязательно)
Мы будем использовать Docker для запуска нашего локального экземпляра DynamoDB - но не только этого.
SAM также сильно зависит от Docker. Когда SAM CLI вызывает локальную лямбда-функцию, SAM запускает контейнер Docker, выполняет лямбда-код и уничтожает контейнер.
Давайте сначала создадим сеть моста Docker. Мы будем использовать этот тип сети Docker, чтобы наши контейнеры Docker могли взаимодействовать друг с другом, разрешая их имена контейнеров. Таким образом, мы можем общаться с нашим локальным контейнером Docker DynamoDB изнутри наших лямбда-контейнеров, управляемых SAM. Контейнер DynamoDB называется динамодб.
$ docker network create sam-demo
$
docker run --network sam-demo --name dynamodb -d -p 8000:8000 amazon/dynamodb-local
Когда контейнер запущен и работает, мы можем создать нашу таблицу DynamoDB. Первичный ключ нашей DynamoDB будет состоять из ключа разделения (documentId) и ключа сортировки (versionId).
$ aws dynamodb create-table --table-name documentTable --attribute-definitions AttributeName=documentId,AttributeType=N AttributeName=versionId,AttributeType=S --key-schema AttributeName=documentId,KeyType=HASH AttributeName=versionId,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 --endpoint-url http://localhost:8000
Использование SAM для создания и вызова локальной функции
Теперь клонируйте демонстрационный проект с GitHub.
Этот проект содержит template.yaml
, который полностью описывает, как должен выглядеть стек. Он развертывает одну автономную лямбда-функцию с именем LoadDataFunction
, которую мы запускаем вручную для загрузки данных в таблицу DynamoDB. Вторая функция называется GetDocumentFunction и запускается событием шлюза API.
Мы можем проверить, действителен ли шаблон:
$ cd aws-lambda-sam-demo $ sam validate -t template.yml xxx/template.yaml is a valid SAM Template
LoadDataFunction будет использоваться для заполнения нашей таблицы DynamoDB. Соберите функции с помощью SAM CLI. Если в вашей локальной среде не установлен Python3.7, вы можете использовать параметр --use-container
для создания функции внутри контейнера Docker.
$ sam build --use-container
Это создает наши лямбда-функции, как описано в нашем template.yaml. Шаблоны SAM являются расширением шаблонов CloudFormation. Сборка загрузит необходимые зависимости, описанные в нашем requirements.txt
, и создаст артефакты развертывания, хранящиеся в .aws-sam/build/functionName
.
LoadDataFunction
нужно выполнить только один раз, чтобы поместить существующие документы и их расположение в нашу таблицу DynamoDB. Давайте подробнее рассмотрим саму функцию:
Мы можем использовать SAM для вызова функции. Мы используем параметр, чтобы указать на нашу среду. Допустимые варианты: local
или aws
. Лямбда-функция подключается к правильной конечной точке DynamoDB на основе этого параметра.
Локальная лямбда-функция будет работать внутри контейнера Docker. Мы говорим SAM развернуть контейнер в той же сети Docker Bridge, что и наш контейнер DynamoDB. Теперь наша лямбда может взаимодействовать с контейнером DynamoDB, используя его имя.
$ sam local invoke LoadDataFunction --parameter-overrides ParameterKey=Environment,ParameterValue=local ParameterKey=DDBTableName,ParameterValue=documentTable --docker-network sam-demo
Когда лямбда-функция успешно завершится, мы сможем увидеть, правильные ли данные находятся в нашей таблице DynamoDB. Отсканируйте содержимое таблицы:
$ aws dynamodb scan --table-name documentTable --endpoint-url http://localhost:8000
Используйте SAM для создания образца полезной нагрузки
Следующая функция - GetDocumentFunction
. Это инициируется событием шлюза API.
Настройка шлюза API определена в template.yaml
. Мы развертываем интеграцию лямбда-прокси шлюза API, где GetDocumentFunction
будет срабатывать, когда к API-GW-URL/document?documentId=xxx&versionId=xxx
поступает запрос GET.
Прежде чем мы развернем эту конечную точку шлюза API, я хочу, чтобы мы протестировали GetDocumentFunction
. Здесь мне нужно создать действительное событие, которое может запускать эту функцию. Следующая команда создаст действительный JSON, который мы можем использовать как поддельное событие шлюза API для запуска лямбда-выражения.
$ sam local generate-event apigateway aws-proxy --method GET --path document --body "" > local-event.json
К сожалению, SAM CLI не поддерживает (пока?) queryStringParameters
во время генерации событий. Поэтому мы должны обновить это вручную в local-event.json
. Помните, мы видели документ с documentId 1044
и version_id v_1 in DynamoDB
, поэтому мы можем использовать их как допустимые значения параметров:
... "queryStringParameters": { "documentId": "1044", "versionId": "v_1" }, ...
Теперь протестируйте GetDocumentFunction
, вызвав его с помощью нашего события:
sam local invoke GetDocumentFunction --event local-event.json --parameter-overrides ParameterKey=Environment,ParameterValue=local ParameterKey=DDBTableName,ParameterValue=documentTable --docker-network sam-demo
Настройка конечной точки локального шлюза API с интеграцией лямбда-прокси
Сотрудники компании будут использовать статический веб-сайт для выполнения действительного запроса GET к шлюзу API. Сотрудники заполняют documentId
и versionId
нужного им документа.
API Gateway перенаправит запрос на наш GetDocumentFunction
. GetDocumentFunction
будет использовать queryStringParameters
для запроса правильного расположения в таблице DynamoDB.
Запустите нашу локальную конечную точку шлюза API:
$ sam local start-api --parameter-overrides ParameterKey=Environment,ParameterValue=local ParameterKey=DDBTableName,ParameterValue=documentTable --docker-network sam-demo
Репозиторий содержит базовую статическую веб-страницу в качестве визуализации. Сотрудники будут использовать это для разговора со шлюзом API. Шлюз API общается с серверной частью, которая является нашим GetDocumentFunction
.
Это фактически выполнит следующий вызов GET:
$ curl "http://127.0.0.1:3000/document?documentId=1044&versionId=v_1"
Теперь нажмите «Отправить запрос». Это вызовет нашу лямбду.
Теперь я показал, как мы можем собрать и протестировать наш стек локально. После внесения изменений в ваш шаблон или лямбда-выражения вы должны снова запустить команду sam build
и повторно активировать или повторно развернуть свои ресурсы.
Вот и все! Если у вас есть доступная учетная запись AWS, вы можете перейти к следующему шагу.
Разверните стек SAM в AWS (необязательно)
Теперь я покажу вам, как легко развернуть этот стек в AWS.
Мы уже выполнили sam build
команду. Это привело к созданию наших артефактов развертывания в каталоге .aws-sam/build/
.
sam deploy
упаковывает и разворачивает наш стек. Мы должны указать корзину S3, в которую мы загружаем наши артефакты развертывания. Обратите внимание, что теперь мы указываем на AWS как на среду, а не на local
. Теперь наши лямбды знают, что они должны подключаться к конечной точке AWS DynamoDB, а не к нашей локальной конечной точке.
$ sam deploy --template-file .aws-sam/build/template.yaml --s3-bucket lvthillo-sam-upload-bucket --parameter-overrides ParameterKey=Environment,ParameterValue=aws ParameterKey=DDBTableName,ParameterValue=documentTable --stack-name aws-lambda-sam-demo --capabilities CAPABILITY_NAMED_IAM
После успешного развертывания мы должны сначала запустить LoadDataFunction
, чтобы заполнить нашу DynamoDB. Просто создайте пустое тестовое событие в лямбда-консоли и выполните функцию:
Правильные данные доступны в DynamoDB:
Теперь мы можем снова протестировать нашу интеграцию лямбда-прокси API Gateway:
Все работает! Наконец, мы можем повторно развернуть наш статический веб-сайт в сегменте S3, который создается нашим стеком. В этой демонстрации я использую public-static-site-bucket как bucket. Шаблон будет генерировать случайное имя сегмента, настроенного как статический веб-сайт.
Нам просто нужно обновить наше статическое приложение, чтобы оно указывало на правильный URL-адрес шлюза API. Чтобы найти этот URL, вы можете перейти в CloudFormation. Найдите свой стек и проверьте выходы. Стек настроен для вывода конечной точки шлюза API.
Для быстрого тестирования мы можем использовать curl
и правильные (или неправильные) параметры.
$ curl "https://c8517wsgol.execute-api.eu-west-1.amazonaws.com/v1/document?documentId=1044&versionId=v_1"
Теперь мы можем обновить наше статическое приложение с помощью этого URL:
Теперь, когда мы обновили URL-адрес, мы можем загружать файлы в корзину S3. Обязательно сделайте объекты общедоступными во время или после загрузки.
Посетите свою корзину S3 как статический веб-сайт!
Правильный URL-адрес также выводится в консоли CloudFormation.
Заключение
Мы открыли для себя волшебство модели бессерверного приложения AWS.
Мы рассмотрели большинство важных вещей, которые вы можете с ним сделать. Мы использовали шаблон SAM для развертывания и тестирования лямбда-функций на нашей локальной машине. Мы даже развернули локальный API-шлюз! Убедившись, что все работает, мы развернули точно такой же стек на AWS.
Надеюсь, вам понравилось. Спасибо, что прочитали, и не стесняйтесь задавать любые вопросы!