Поиск по сайту:

Как создать лямбда-функции с помощью SAM


Хотя в Lambda есть веб-редактор для обновления ваших функций, он предназначен для начинающих и не является тем, что вам следует использовать на практике. Создание функций с помощью шаблонов SAM позволяет перенести функции Lambda в существующую систему управления версиями и конвейер CI/CD.

Проблема

Если вы изучаете AWS и Lambda, вы, вероятно, видели этот интерфейс:

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

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

Решением является бессерверная модель приложений AWS, сокращенно SAM. AWS почему-то характеризует SAM как белку:

Однако на самом деле SAM — это шаблон YAML. В шаблоне вы определяете свое приложение и все необходимые ему ресурсы (например, отдельные функции Lambda). Вместо того, чтобы обновлять свои функции вручную, вы можете развертывать обновления через SAM, который сделает это за вас и обновит все ваши функции одновременно.

SAM — это расширение AWS CloudFormation. У них почти одинаковый синтаксис, но SAM оптимизирован и специально разработан для Lambda. Всякий раз, когда вносится и развертывается новое изменение, SAM обновляет стек CloudFormation, созданный при первоначальном развертывании шаблона.

Поскольку SAM — это всего лишь файл YAML, его можно отслеживать и управлять версиями вместе со всеми вашими функциями. Это позволяет включить его в конвейер CI/CD для автоматизации сборки и развертывания прямо из Git. Когда все настроено, вы можете хранить свои функции Lambda в репозитории Git, и всякий раз, когда вы отправляете новые коммиты, CodePipeline примет новые изменения и автоматически запустит развертывание SAM для создания новой версии Lambda. Он даже способен замедлять перемещение трафика между версиями с помощью балансировки трафика псевдонимов, что может помочь вам выявлять ошибки до того, как они станут проблемами.

Если вы хотите узнать больше об использовании SAM в конвейере CI/CD для автоматизации развертываний Lambda, вы можете прочитать наше руководство по этому вопросу здесь. Однако сейчас мы сосредоточимся на использовании самого SAM и ручном развертывании из CLI.

Как написать файл SAM

Типичный файл SAM будет иметь следующий базовый формат:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An AWS Serverless Specification template describing your function
Resources:
  HelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler:  HelloWorld/index.handler
      Runtime: nodejs8.10

Этот шаблон просто определяет несколько переменных конфигурации, а затем в разделе «Ресурсы» определяет функции Lambda по имени. Например, здесь мы создаем функцию под названием «HelloWorld». эта функция работает на nodejs8.10, а ее обработчик (начальная точка) находится в подкаталоге файла index.js .

Мы можем сохранить этот шаблон как template.yml и поместить его в каталог проекта рядом с отдельными каталогами, содержащими код функции.

ProjectDirectory
  |- template.yml
  |- HelloWorld
      |-index.js

Это уже представляет собой гораздо более простой способ управления функциями Lambda. Несколько функций можно упаковать в один шаблон и развернуть все сразу.

Однако Lambda — это не просто код, и для его работы требуется гораздо больше настроек. В частности, функции Lambda нуждаются в событии для запуска. Вы можете определить это в разделе «Свойства» для функции. Например, чтобы настроить функцию на запуск шлюза API.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An AWS Serverless Specification template describing your function
Resources:
  HelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler:  HelloWorld/index.handler
      Runtime: nodejs8.10
      Events:
        HelloWorldApi:
          Type: Api
          Properties:
            Path: /helloworld
            Method: GET

Когда это будет развернуто, новый шлюз API для проекта Lambda будет автоматически создан SAM в CloudFormation и связан с вновь созданной функцией по указанным путям.

SAM поддерживает все другие типы источников событий Lambda. Вы можете найти больше документации для других типов на странице SAM Github.

SAM также может развертывать не только функции Lambda. Поскольку это полное расширение CloudFormation, вы можете развертывать другие ресурсы, которые потребуются вашему приложению, все из SAM. Например, при использовании Lambda с API Gateway вам потребуется предоставить разрешение API Gateway для вызова вашей функции. Это можно сделать с помощью следующего фрагмента кода, определяющего ресурс AWS::Lambda::Permission :

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An AWS Serverless Specification template describing your function
Resources:
  HelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler:  HelloWorld/index.handler
      Runtime: nodejs8.10
  HelloWorldPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Fn::GetAtt:
        - HelloWorld
        - Arn
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Sub: arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*/*/*

Это немного сложнее, но по сути дает шлюзу API разрешение на вызов функции в свойстве FunctionName. Fn::GetAtt – это встроенная функция, которая возвращает ARN для функции HelloWorld, потому что вы не знаете, каким будет точный ARN.

Это лишь малая часть того, что может сделать SAM. Для получения дополнительной информации о спецификации шаблона SAM вы можете ознакомиться с полной схемой на Github или прочитать Руководства разработчика AWS по использованию SAM.

Развертывание SAM-файла

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

У SAM есть собственный CLI, отличный от стандартного AWS. Вы можете установить его из pip:

pip install aws-sam-cli

Во-первых, вам нужно все упаковать и отправить артефакты в корзину S3:

sam package 
--template-file template.yml 
--output-template-file package.yml 
--s3-bucket bucket-name

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

sam deploy 
--template-file package.yml 
--stack-name sam-hello-world 
--capabilities CAPABILITY_IAM

Обратите внимание, что эта команда развертывает стек с определенным именем, определенным этой командой; в самом шаблоне SAM нет ничего, что задавало бы имя стека. Если вы хотите развернуть новый стек, вы можете изменить это имя здесь. В противном случае оставьте то же имя, и стек будет обновлен.

Когда развертывание SAM завершится, вы увидите новое приложение с вашими функциями, а также новый стек в CloudFormation: