Если вы хотите пропустить краткое введение ниже, вы можете сразу перейти к первым четырем триггерам с помощью этих коротких ссылок:

  1. Пулы пользователей Amazon Cognito - управление пользователями и настраиваемые рабочие процессы
  2. AWS Config - проверка конфигурации на основе событий
  3. Amazon Kinesis Data Firehose - прием и проверка данных
  4. AWS CloudFormation - IaC, макросы и пользовательские преобразования

Сначала немного истории

Когда AWS Lambda стала общедоступной 9 апреля 2015 года, она стала первой из существующих функций функция как услуга, и было всего несколько способов запускать свои функции, помимо прямого вызова: Amazon S3, Amazon Kinesis и Amazon SNS. Три месяца спустя мы получили поддержку Amazon API Gateway, которая открыла новую волну для Интернета и REST-совместимых клиентов.

К концу 2015 года вы уже могли запускать функции через Amazon DynamoDB Streams, Kinesis Streams, объекты S3, темы SNS и события CloudWatch (запланированные вызовы).

Лично я начал экспериментировать с AWS Lambda примерно в начале 2016 года для простого случая использования машинного обучения. Через несколько месяцев я опубликовал самое первое видео о своем опыте работы с Lambda, в котором были описаны все доступные триггеры и конфигурации, доступные в то время; ну, видео по-прежнему доступно здесь, но консоль AWS теперь сильно изменилась, поэтому я рекомендую вам посмотреть ее, только если вы испытываете ностальгию =)

Вернуться к истории…

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

Возможно, вы уже знаете (или интуитивно догадываетесь), как AWS Lambda интегрируется с такими сервисами, как S3, DynamoDB, Kinesis Data Streams, SES, SQS, IoT Core, Step Functions. , и ALB. И есть множество статей и руководств по началу работы, в которых эти интеграции используются в качестве хорошей отправной точки для вашего бессерверного путешествия.

В этой статье я хотел бы поделиться с вами некоторыми из множества других менее распространенных, менее известных или даже просто новых способов вызова ваших функций Lambda на AWS. Некоторые из этих интеграций еще даже не появились на официальной странице документации Поддерживаемые источники событий, и я считаю, что их стоит упомянуть и поэкспериментировать.

Для каждой службы / интеграции я поделюсь полезными ссылками, фрагментами кода, а также шаблонами и ссылками CloudFormation. Не стесняйтесь добавлять комментарий ниже, если вы считаете, что чего-то не хватает или вам нужны дополнительные ресурсы / подробности. Даже если вы не знаете Python или JavaScript, код будет довольно понятным и с полезными комментариями. Пожалуйста, оставьте комментарий в Gist или внизу этой статьи, если у вас есть вопросы или сомнения.

Давайте начнем с первых 4 триггеров для AWS Lambda.

1. Пулы пользователей Amazon Cognito (настраиваемые рабочие процессы)

Пулы пользователей Cognito позволяют добавлять в свои приложения аутентификацию и управление пользователями. С помощью AWS Lambda вы можете настраивать рабочие процессы пула пользователей и запускать свои функции во время операций Cognito, чтобы настроить поведение пула пользователей.

Вот список доступных триггеров:

  • Предварительная регистрация - запускается непосредственно перед тем, как Cognito зарегистрирует нового пользователя (или администратора), и позволяет выполнить настраиваемую проверку, чтобы принять / отклонить его.
  • Подтверждение публикации - срабатывает после регистрации нового пользователя (или администратора) и позволяет отправлять настраиваемые сообщения или добавлять настраиваемую логику.
  • Предварительная проверка подлинности - срабатывает, когда пользователь пытается войти в систему, и позволяет настраиваемой проверке принять / отклонить ее.
  • Пост-аутентификация - запускается после входа пользователя в систему и позволяет добавить пользовательскую логику после аутентификации.
  • Настраиваемая проверка подлинности - запускается для определения, создания и проверки настраиваемых задач при использовании настраиваемого потока проверки подлинности.
  • Предварительное создание токена - запускается перед каждым созданием токена и позволяет настраивать утверждения токена идентификации (например, новые пароли и токены обновления).
  • Перенести пользователя - запускается, когда пользователь не существует в пуле пользователей во время входа с паролем или в потоке забытых паролей.
  • Пользовательское сообщение - срабатывает перед отправкой электронного письма, сообщения с подтверждением по телефону или кода MFA и позволяет настроить сообщение.

Все эти триггеры позволяют реализовать логику без состояния и персонализировать работу пользовательских пулов Cognito, используя ваш любимый язык программирования. Имейте в виду, что ваши функции вызываются синхронно и должны быть выполнены в течение 5 секунд, просто путем возврата входящего объекта event с дополнительным атрибутом response.

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

Например, вот как можно реализовать код функции Lambda для Custom Message в Node.js:

Как видите, логика полностью не имеет состояния, и рекомендуется всегда проверять значение triggerSource, чтобы убедиться, что вы обрабатываете правильное событие, и, в конечном итоге, вызывать ошибку / предупреждение в случае необработанных источников.

В следующем фрагменте кода показано, как определить функцию Lambda и пул пользователей Cognito в шаблоне CloudFormation (здесь я использую синтаксис AWS SAM, но вы также можете использовать простой CloudFormation):

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

Вы можете найти все атрибуты LambdaConfig на странице документации.

2. AWS Config (проверка конфигурации на основе событий)

AWS Config позволяет отслеживать, как конфигурации ваших ресурсов AWS меняются с течением времени. Это особенно полезно для записи исторических значений, а также позволяет сравнивать исторические конфигурации с желаемыми конфигурациями. Например, вы можете использовать AWS Config, чтобы убедиться, что все экземпляры EC2, запущенные в вашей учетной записи, t2.micro.

Как разработчик, интересная часть заключается в том, что вы можете реализовать такого рода проверки соответствия с помощью AWS Lambda. Другими словами, вы можете определить собственное правило и связать его с лямбда-функцией, которая будет вызываться в ответ на каждое изменение конфигурации (или периодически).

Кроме того, ваш код может решить, действительна новая конфигурация или нет :)

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

  • Теги (например, ресурсы с тегом среды или проекта)
  • Тип ресурса (например, только AWS::EC2::Instance)
  • Тип ресурса + идентификатор (например, ARN определенного экземпляра EC2)
  • Все изменения

Существует множество схем AWS Lambda, которые позволяют быстро приступить к работе, не кодируя все самостоятельно (например, config-rule-change-triggered). Но я думаю, что важно понимать общую логику и движущиеся части, поэтому в следующих нескольких абзацах мы углубимся и узнаем, как написать новую лямбда-функцию с нуля.

Фактически, ваша функция получит четыре очень важных элемента информации как часть входных event:

  • invokingEvent представляет изменение конфигурации, вызвавшее этот вызов лямбда-выражения; он содержит поле с именем messageType, которое сообщает вам, связана ли текущая полезная нагрузка с периодическим запланированным вызовом (ScheduledNotification), если это обычное изменение конфигурации (ConfigurationItemChangeNotification) или если содержимое изменения было слишком большим для включения в полезную нагрузку события Lambda ( OversizedConfigurationItemChangeNotification); в первом случае invokingEvent также будет содержать поле с именем configurationItem с текущей конфигурацией, а в других случаях нам нужно будет получить текущую конфигурацию через API истории AWS Config.
  • ruleParameters - это набор пар ключ / значение, который вы опционально определяете при создании настраиваемого правила; они представляют (не) желаемый статус ваших конфигураций (например, desiredInstanceType=t2.small), и вы можете использовать их значения, как хотите; допустим, это умный способ параметризовать код лямбда-функции и повторно использовать его с несколькими правилами.
  • resultToken - это токен, который мы будем использовать при уведомлении AWS Config о результатах оценки конфигурации (см. Три возможных результата ниже).
  • eventLeftScope сообщает вам, был ли ресурс AWS, который должен быть оценен, удален из области действия правила, и в этом случае мы просто пропустим оценку.

На основе введенных выше данных наша лямбда-функция оценит соответствие конфигурации и сможет вызвать PutEvaluations API с тремя возможными результатами:

  • COMPLIANT, если текущая конфигурация ОК
  • NON_COMPLIANT, если текущая конфигурация НЕ ОК
  • NOT_APPLICABLE если это изменение конфигурации можно игнорировать

Хорошо, хватит теории :)

Давайте напишем код и посмотрим, как работает AWS Config.

Например, давайте реализуем специальное правило, чтобы проверить, что все экземпляры EC2, запущенные в нашей учетной записи, t2.small используют Node.js:

В приведенном выше фрагменте кода я импортирую простой служебный модуль (который вы можете найти здесь), чтобы сделать общую логику более читаемой.

Большая часть волшебства происходит в функции JavaScript с именем evaluateChangeNotificationCompliance. Его логика параметризована на основе ruleParameters и значения desiredInstanceType, которое мы определим в шаблоне CloudFormation ниже, чтобы мы могли повторно использовать одну и ту же функцию Lambda для разных правил.

Теперь давайте определим наше настраиваемое правило AWS Config и функцию Lambda в CloudFormation:

Определение настраиваемого правила довольно интуитивно понятно. В свойстве Scope я выбираю только AWS::EC2::Instance ресурсов и передаю t2.small в качестве входного параметра настраиваемого правила. Затем я определяю свойство Source и ссылаюсь на свою лямбда-функцию.

Вы можете найти полную документацию о пользовательских правилах AWS Config здесь с хорошими ссылками на запланированные правила, фильтрацию тегов и т. Д.

3. Amazon Kinesis Data Firehose (проверка данных)

Kinesis Data Firehose позволяет принимать потоковые данные в стандартные места назначения для аналитических целей, такие как Amazon S3, Amazon Redshift, Amazon Elasticsearch Service и Splunk.

У вас может быть несколько производителей данных, которые PutRecords будут добавлены в ваш поток доставки. Kinesis Firehose позаботится о буферизации, сжатии, шифровании и, при необходимости, даже изменении формы и оптимизации ваших данных для выполнения запросов (например, в столбчатом формате Parquet).

Кроме того, вы можете присоединить к потоку доставки лямбда-функцию. Эта функция сможет проверять, изменять или дополнять входящие записи до того, как Kinesis Firehose продолжит работу.

Ваша лямбда-функция получит пакет записей и должна будет вернуть тот же список записей с дополнительным полем result, значение которого может быть одним из следующих:

  • Ok, если запись была успешно обработана / проверена
  • Dropped, если запись не нужно сохранять (Firehose просто пропустит ее)
  • ProcessingFailed если запись недействительна или что-то пошло не так во время ее обработки / манипуляции

Давайте теперь реализуем в Python универсальную и многократно используемую логику проверки и управления:

Приведенный выше фрагмент кода структурирован так, что вам нужно только реализовать свою собственную transform_data логику. Там вы можете добавлять новые поля, управлять существующими или решить пропустить / отбросить текущую запись, подняв DroppedRecordException.

Стоит упомянуть несколько деталей реализации:

  • И входящие, и исходящие записи должны быть в кодировке base64 (фрагмент выше уже позаботился об этом).
  • Я предполагаю, что входящие записи находятся в формате JSON, но вы также можете принимать данные CSV или даже свой собственный формат; просто убедитесь, что вы (де) сериализуете записи правильно, поскольку Kinesis Firehose всегда рассчитывает работать с простыми строками
  • Я добавляю завершающий символ \n после каждой закодированной записи, чтобы Kinesis Firehose сериализовал по одному объекту JSON на строку в пункте назначения доставки (это необходимо для правильной работы Amazon S3 и Athena)

Конечно, вы можете реализовать собственную логику манипулирования данными на любом языке программирования, поддерживаемом AWS Lambda, и - в некоторых более сложных случаях использования - вам может потребоваться получить дополнительные данные из Amazon DynamoDB или других источников данных.

Теперь давайте определим наше приложение для приема данных в CloudFormation.

Вы можете присоединить лямбда-функцию к потоку доставки Kinesis Firehose, определив атрибут ProcessingConfiguration.

В дополнение к этому, давайте настроим Firehose для доставки входящих записей в Amazon S3 каждые 60 секунд (или как только будет собрано 10 МБ), сжатые с помощью GZIP . Нам также понадобится специальная роль IAM, чтобы определить детализированные разрешения для Firehose для вызова нашей Lambda и записи в S3.

Вот полный шаблон CloudFormation для справки:

На мой взгляд, лучшая часть этой архитектуры состоит в том, что она на 100% бессерверна, и с вас не будет взиматься плата, если данные не поступают. Таким образом, вы можете иметь несколько сред, работающих круглосуточно и без выходных, для разработки и тестирования практически бесплатно.

Вы можете найти полную документацию по CloudFormation здесь. Кроме того, здесь вы найдете сквозной конвейер, включая Amazon API Gateway и Amazon Athena.

4. AWS CloudFormation (макросы)

Мы уже видели много шаблонов CloudFormation в этой статье. Вот как вы определяете свои приложения и ресурсы в шаблоне JSON или YAML. CloudFormation позволяет развернуть один и тот же стек в нескольких учетных записях AWS, регионах или средах, таких как dev и prod.

Несколько месяцев назад - в сентябре 2018 года - AWS анонсировала новую функцию CloudFormation под названием Macros.

CloudFormation имеет встроенные преобразования, такие как AWS::Include и AWS::Serverless, которые упрощают создание шаблонов за счет сжатия выражений определения ресурсов и возможности повторного использования компонентов. Эти преобразования применяются к вашим шаблонам CloudFormation во время развертывания.

Точно так же Макрос CloudFormation - это настраиваемое преобразование, поддерживаемое вашей собственной лямбда-функцией.

Создание и использование макроса состоит из трех основных шагов:

  1. Создайте лямбда-функцию, которая будет обрабатывать необработанный шаблон
  2. Определите ресурс типа AWS::CloudFormation::Macro (ссылка на ресурс здесь), сопоставьте его с функцией Lambda выше и разверните стек.
  3. Использование макроса в шаблоне CloudFormation

Макросы особенно эффективны, потому что вы можете применять их либо ко всему шаблону CloudFormation - используя свойство Transform, - либо только к подсекции - с помощью встроенной Fn :: Transform function, необязательно с параметрами.

Например, вы можете определить макрос, который расширит простой ресурс MyCompany::StaticWebsite на соответствующий набор ресурсов и соответствующие значения по умолчанию, включая сегменты S3, распределения CloudFront, роли IAM, аварийные сигналы CloudWatch и т. Д.

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

Как реализовать макрос CloudFormation

Теперь сосредоточимся на деталях реализации лямбда-функции, выполняющей обработку шаблона.

Когда ваша функция вызывается, она получает в качестве входных данных следующее:

  • region - это регион, в котором находится макрос
  • accountID - это идентификатор учетной записи, вызывающей эту функцию.
  • fragment - это часть шаблона, доступная для обработки (может быть весь шаблон или только его часть) в формате JSON, включая братьев и сестер.
  • params доступен только в том случае, если вы обрабатываете подраздел шаблона и он содержит настраиваемые параметры, предоставленные целевым стеком (не оцениваются)
  • templateParameterValues содержит параметры шаблона целевого стека (уже оцененные)
  • requestId - это идентификатор текущего вызова функции (используется только для сопоставления ответа)

После завершения логики обработки лямбда-функция должна будет вернуть следующие три атрибута:

  • requestId должен соответствовать тому же идентификатору запроса, который указан во входных данных.
  • status должен быть установлен в строку "success" (все остальное будет рассматриваться как сбой обработки)
  • fragment - обработанный шаблон, включая братьев и сестер

Интересно отметить, что в некоторых случаях обработанноеfragment будет таким же fragment, которое вы получили в качестве входных данных.

Я мог придумать четыре возможных сценария манипуляции / обработки:

  1. Ваша функция обрабатывает некоторые ресурсы и настраивает их свойства (без добавления и удаления других ресурсов)
  2. Ваша функция расширяет входной фрагмент, создавая новые ресурсы
  3. Ваша функция заменяет некоторые ресурсы - возможно, ваши собственные типы - другими реальными ресурсами CloudFormation (обратите внимание: это то, что делает AWS SAM!)
  4. Ваша функция не изменяет входной фрагмент, но намеренно завершается ошибкой, если что-то не так или отсутствует (например, если шифрование отключено или предоставленные разрешения слишком открыты)

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

На мой взгляд, сценарий (4) особенно эффективен, поскольку он позволяет вам реализовать пользовательские проверки конфигурации до того, как ресурсы будут фактически развернуты и подготовлены по отношению к решению AWS Config. мы обсуждали в начале этой статьи.

Сценарий (3), вероятно, наиболее часто используется, поскольку он позволяет вам определять свои собственные персонализированные ресурсы, такие как MyCompany::StaticWebsite (с сегментами S3, дистрибутивами CloudFront или приложениями консоли Amplify) или MyCompany::DynamoDB::Table (с включенным автомасштабированием , емкость по запросу или даже сложная общая конфигурация для первичного ключа и индексов) и т. д.

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

Здесь вы можете найти реальные примеры реализации макросов CloudFormation, соответствующие шаблоны макросов, а также несколько образцов шаблонов. Я совершенно уверен, что вам особенно понравятся следующие макросы: AWS::S3::Object, Count, StackMetrics, StringFunctions и другие!

Как развернуть макрос CloudFormation

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

Вот как вы определяете новый макроресурс:

Вот и все!

AWS CloudFormation будет вызывать функцию обработки каждый раз, когда мы ссылаемся на макрос с именем MyUniqueMacroName в шаблоне CloudFormation.

Как использовать макрос CloudFormation

Использование макроса - наиболее вероятный сценарий для большинства разработчиков.

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

Вот как вы можете использовать макрос, определенный выше, и применить его ко всему шаблону:

Если вы хотите применить тот же макрос только к подразделу вашего шаблона, вы можете сделать это с помощью встроенной функции Fn::Transform:

Сообщите мне, какие макросы CloudFormation вы создадите и какие задачи они решают для вашей команды!

Выводы

На этом все по части 1 :)

Надеюсь, вы узнали что-то новое об Amazon Cognito, AWS Config, Amazon Kinesis Data Firehose и Amazon CloudFormation.

Теперь вы можете настроить рабочий процесс Cognito User Pools, проверять свои конфигурации в режиме реального времени, управлять данными и проверять их до того, как Kinesis доставит их в место назначения, а также реализовать макросы для обогащения ваших шаблонов CloudFormation.

В следующих двух частях этой серии мы узнаем больше о других менее распространенных интеграциях Lambda для таких сервисов, как AWS IoT 1-Click, Amazon Lex, Amazon CloudWatch Logs, AWS CodeDeploy и Amazon Aurora.

Спасибо, что нашли время прочитать такую ​​длинную статью.
Не стесняйтесь поделиться и / или оставить комментарий ниже.