Создание функций AWS Lambda может быть неприятным занятием. Каждый раз, когда вы вносите изменения, вам необходимо развернуть свой код в AWS, прежде чем вы сможете его протестировать. Что ж, мой друг и я все-таки решили что-то с этим делать.

Конечным результатом является Плагин бессерверного моделирования. Этот плагин представляет собой симулятор AWS Lambda и API Gateway для Serverless Framework.

Я расскажу вам, как мы это создали и как вы можете начать использовать его при разработке бессерверных приложений.

Моделирование API-шлюза

API Gateway предоставляет конечные точки HTTP, которые вызывают функции Lambda в ответ на запросы.

API Gateway сопоставляет входящий HTTP-запрос с полезной нагрузкой события для Lambda. Когда функция Lambda возвращает результат, результат сопоставляется с ответом HTTP.

Хотя API Gateway имеет множество функций, большинство разработчиков используют лишь некоторые из них. Мы решили реализовать только те функции, которые обычно используются бессерверными разработчиками.

HTTP-сервер

Для имитации API Gateway плагин создает HTTP-сервер с экспрессом. Плагин читает бессерверный конфигурационный файл и создает конечные точки из HTTP-событий.

Если конечная точка включила CORS, плагин добавит в конечную точку CORS Middleware.

Пользовательские авторизаторы

API Gateway может авторизовать конечные точки несколькими способами. Обычный подход - использовать Custom Authorizer.

Для имитации пользовательских авторизаторов мы создали функцию промежуточного программного обеспечения express js. По промежуточного слоя создает событие Lambda с информацией об авторизации из запроса. Затем функция Authorizer вызывается локально.

Пользовательские авторизаторы разрешают или отклоняют запросы на основе документа политики. По промежуточного слоя читает документ политики, возвращенный авторизатором. Если запросу не разрешен доступ к конечной точке, промежуточное ПО вернет ответ Неавторизованный.

Лямбда-интеграция

API Gateway имеет две интеграции с AWS Lambda. Оригинальная Лямбда-интеграция и более новый Лямбда-прокси.

Обе интеграции сопоставляют HTTP-запросы с событием Lambda. Когда Lambda возвращает результат, интеграция сопоставляет результат с ответом HTTP.

Мы разработали две функции сопоставления, имитирующие лямбда-прокси и лямбда-прокси. Сервер выбирает интеграцию на основе конфигурации события HTTP в serverless.yml.

Когда запрос получен, сервер выполняет тот же процесс сопоставления, что и API-шлюз. Ниже представлена ​​упрощенная версия кода.

function(req, res) {
  integration.event(req)
    .then(event => lambda.invoke(context, event))
    .then(result => integration.response(req, result))
    .then(response => respond(res, response))
}

Конечным результатом является экспресс-сервер, который ведет себя как API Gateway.

Использование имитатора шлюза API

Чтобы использовать симулятор API Gateway, вам необходимо установить плагин в бессерверный проект. Пожалуйста, прочтите документацию для получения инструкций.

Чтобы запустить симулятор шлюза API, выполните следующую команду:

sls simulate apigateway -p 5000

Это запустит HTTP-сервер, который вы можете использовать для локального тестирования ваших конечных точек и функций.

Моделирование шлюза API похоже на другие автономные плагины для Serverless Framework. Настоящая разница с бессерверным моделированием заключается в том, как мы моделируем лямбду локально.

Моделирование AWS Lambda

AWS Lambda работает на основе HTTP API. Функции вызываются через HTTP-запрос к Lambda API.

Когда вызывается Invoke API, служба Lambda запускает ваш код внутри контейнера. Подробнее см. Документацию.

Хотя AWS Lambda представляет собой сложный сервис, основные элементы достаточно легко смоделировать. Чтобы моделировать его локально, мы реализовали три сервиса: время выполнения функций, реестр функций и HTTP API.

Время выполнения функции

Мы используем образ Docker, созданный Майклом Хартом для создания среды выполнения функции. Использование Docker позволяет нам контролировать среду и применять ограничения памяти и тайм-ауты.

Реестр функций

Реестр функций - это локальная база данных JSON на базе lowdb. В реестре хранится информация о конфигурации и расположении функции.

Это позволяет серверу искать подробную информацию о функции, когда API получает запрос.

HTTP API

HTTP API предоставляет клиентам конечную точку регистрации. Конечная точка регистрации используется плагином для регистрации функций.

HTTP API также предоставляет конечную точку для вызова функций. Конечная точка вызова имитирует API AWS Lambda. Это позволяет клиентам использовать AWS SDK для вызова функций.

Зачем использовать симулятор лямбда

Симулятор Lambda позволяет вам вызывать функции Lambda локально из других служб. Это может включать другую функцию Lambda в другой бессерверной службе. Или это может быть совершенно другое приложение.

Это полезно, если вы связываете функции Lambda или переносите существующее приложение на AWS Lambda.

Например, эта функция локально вызывает другую лямбда-функцию. Без Lambda Simulator вторая функция вызывалась бы в AWS.

// If offline use the local registry
const endpoint = process.env.SERVERLESS_SIMULATE ?
  process.env.SERVERLESS_SIMULATE_LAMBDA_ENDPOINT :
  undefined
// configure the AWS SDK to use the local endpoint
const lambda = new AWS.Lambda({ endpoint })
const handler = (event, context, callback) => {
  const params = {
    FunctionName: 'my-other-function',
    Payload: JSON.stringify({ foo: 'bar' })
  }
lambda.invoke(params, (err, result) => {
    if (err) {
      return callback(err)
    }
    
    callback(null, {
      statusCode: 200,
      body: result.Payload
    })  
  })
}

Использование симулятора лямбда

Чтобы использовать симулятор Lambda, вам необходимо установить плагин в бессерверный проект. Пожалуйста, прочтите документацию для получения инструкций.

Чтобы запустить симулятор лямбда, выполните следующую команду:

sls simulate lambda -p 4000

Чтобы использовать Lambda Simulator со шлюзом API, запустите команду API Gateway с аргументом --lambda-port.

sls simulate apigateway -p 5000 --lambda-port

При использовании аргумента --lambda-port симулятор шлюза API вызывает функции через HTTP API.

Это позволяет моделировать сложные архитектуры локально перед развертыванием в облаке.

Сравнение с другими плагинами

Serverless Offline - самый популярный плагин для Serverless Framework. К сожалению, дизайн Serverless Offline ограничивает качество моделирования.

Этот плагин имитирует API Gateway и выполняет функции в процессе плагина. К минусам этого решения можно отнести:

  • Нет поддержки Python
  • Он использует любую версию NodeJS, которую вы используете, которая может быть не той же версией NodeJS, что и AWS Lambda.
  • Он не применяет ограничения памяти или тайм-ауты
  • Невозможно связать вызовы лямбда-функций

Мы разработали бессерверное моделирование для решения этих проблем.

Иди и строй

Этот плагин поможет решить большую проблему для меня и команды A Cloud Guru. Модульные тесты и локальное выполнение сокращают время ожидания развертывания в облаке.

Бессерверная платформа и бессерверное моделирование - это проекты с открытым исходным кодом. Если вы хотите принять участие, вы можете помочь, создав проблемы или отправив запрос на перенос.

Я надеюсь, что это поможет вам сэкономить время при локальном тестировании лямбда-функций.

Если у вас есть какие-либо вопросы по поводу этого проекта или Serverless в целом, вы можете связаться со мной на Medium или Twitter. Я проведу семинар в ServerlessConf Austin, если вы захотите встретиться со мной лично.