Развертывание ресурсов AWS с помощью serverless framework

В этой статье я покажу вам, как можно развернуть ресурсы AWS с помощью serverless framework и IaaC (Infrastructure As A Code).

Я буду использовать сервисы AWS AWS Lambda и Amazon DynamoDB. Я также буду использовать фреймворк Serverless и NodeJS.

Я покажу, как можно развернуть различные Lambda с помощью serverless, а также как создать таблицу DynamoDB с помощью serverless.

Проект будет представлять собой простое приложение ToDo, в котором мы создадим Lambdas для добавления и получения элемента.

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

Необходимые условия:

  1. учетная запись AWS
  2. Установлен AWS CLI — вот руководство о том, как предоставить доступ AWS CLI к вашей учетной записи AWS
  3. Установлен фреймворк Serverless — руководство здесь

Инициализация проекта

Откройте терминал и введите:

serverless
Войдите в полноэкранный режим Выйти из полноэкранного режима

Теперь вам будет предложено несколько вариантов, выберите:

AWS - Node.js - HTTP API 
Войти в полноэкранный режим Выйти из полноэкранного режима

Добавьте имя вашему проекту или нажмите enter, чтобы выбрать предложенное имя.

Для следующего вопроса я выбрал n:

Do you want to login/register to Serverless Dashboard? n
Войти в полноэкранный режим Выйти из полноэкранного режима

Для следующего вопроса я выбрал n:

Do you want to deploy now? n
Войти в полноэкранный режим Выйти из полноэкранного режима

Откройте только что созданный проект в редакторе, я буду использовать Visual Studio Code.

Открыть проект

Давайте пройдемся по тому, что у нас сейчас есть в структуре проекта:

  • .gitignore
  • handler.js — наш обработчик с созданным образцом модуля
  • README.md
  • serverless.yml — это основной файл, который мы будем создавать для развертывания наших сервисов на AWS

serverless.yml

Сервис настраивается с помощью файла serverless.yml, в котором вы определяете свои функции, события, которые их вызывают, и ресурсы AWS для развертывания.

Наш текущий файл выглядит следующим образом:

service: aws-node-http-api-project
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get
Вход в полноэкранный режим Выход из полноэкранного режима

service = то, как мы называем наш сервис
frameworkVersion = версия используемого бессерверного фреймворка
provider = облачный провайдер, время выполнения для наших функций,
functions = текущие функции, в настоящее время у нас есть одна в нашем handler.js
functions.hello = здесь мы добавили свойства наших функций, такие как обработчик и события, которые вызывают событие.

Команды, которые мы будем использовать

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

  • serverless deploy — Развертывание изменений
  • serverless deploy -f — развертывание определенной функции
  • serverless info — Просмотр развернутых конечных точек и ресурсов
  • serverless invoke — Вызвать развернутые функции
  • serverless —help — Открыть дополнительные команды.

Совет: вы можете использовать команду sls вместо ввода serverless. Например, sls deploy.

Давайте начнем создавать нашу функцию добавления элемента

Начните с добавления папки src в ваш проект и удалите текущий файл handler.js.

Внутри папки src добавьте файл add.js и добавьте следующий код:

const { v4 } = require('uuid')
const AWS = require('aws-sdk')

const add = async (event) => {

  const dynamoDB = new AWS.DynamoDB.DocumentClient();

  const { todo } = JSON.parse(event.body);
  const createdAt = new Date().toDateString()
  const id = v4();

  const newTodo = {
    id,
    todo,
    createdAt,
    completed: false
  };

  await dynamoDB.put({
    TableName: 'TodoTable',
    Item: newTodo
  }).promise();

  return {
    statusCode: 200,
    body: JSON.stringify(newTodo)
  };
};

module.exports = {
  handler: add
}
Вход в полноэкранный режим Выйти из полноэкранного режима

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

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

Прежде всего, мы хотим добавить регион в разделе provider. Добавьте регион, в котором вы хотите создавать свои сервисы, мой находится в region: eu-north-1. Обратите внимание, что отступ важен в .yml файле, и регион должен быть с тем же отступом, что и время выполнения.

Теперь перейдите к разделу функций и удалите функцию hello и начните с добавления следующей функции с отступом на одну вкладку ниже функций:

add: // this is the name of our function
    handler: src/add.handler // our handler which is located in the src folder and is called add.handler
   events: // how we call this function
       - httpApi: // - this dash in .yml means an array which we will use to define multiple parameters
          path: / // no specific path will be used but it could be for example /addItem
          method: post // this is a post
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы готовы развернуть нашу первую функцию Lambda через IaaC. Откройте терминал и введите:

sls deploy
Enter fullscreen mode Выйти из полноэкранного режима

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

Deploying aws-node-http-api-project to stage dev (eu-north-1)

✔ Service deployed to stack aws-node-http-api-project-dev (104s)

endpoint: POST - https://...execute-api.eu-north-1.amazonaws.com/
functions:
  add: aws-node-http-api-project-dev-add (1.9 kB)

Ввести полноэкранный режим Выход из полноэкранного режима

Конечная точка — это то, как вы достигнете этой лямбды, и поскольку мы не добавили никакого конкретного пути, то этой функции достаточно сделать следующее, чтобы добавить новый элемент:

method: POST
endpoint: https://...execute-api.eu-north-1.amazonaws.com/
body: {
           "todo": "My first item"
      }

Войти в полноэкранный режим Выйти из полноэкранного режима

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

Давайте создадим нашу базу данных

Перейдите в ваш файл serverless.yml и добавьте следующее ниже всего раздела функций:

resources:
  Resources:
      TodoTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: TodoTable
          BillingMode: PAY_PER_REQUEST
          AttributeDefinitions:
            - AttributeName: id
              AttributeType: S
          KeySchema:
            - AttributeName: id
              KeyType: HASH
Войти в полноэкранный режим Выйти из полноэкранного режима

Здесь мы сделали следующее:

  1. Создали новый ресурс под названием TodoTable
  2. Тип — AWS::DynamoDB::Table
  3. Мы добавили пару свойств, таких как TableName и BillingMode.
  4. AttributeDefinitions представляет собой атрибут для описания схемы ключей для таблицы и индексов
  5. KeySchema определяет атрибуты, составляющие первичный ключ для таблицы или индекса.

Теперь вы можете развернуть свою инфраструктуру, набрав:

sls deploy
Войти в полноэкранный режим Выйти из полноэкранного режима

Если вы запустите вашу функцию add, вы заметите, что она ничего не запишет в вашу таблицу, и это потому, что наши функции не могут получить доступ к таблице DynamoDB, которую мы только что создали, и для этого нам нужно предоставить роль IAM. Перейдите к провайдеру и в разделе region добавьте следующее:

 iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:*
      Resource:
        - <your DynamoDB's ARN that can be accessed from the console>
Войти в полноэкранный режим Выйти из полноэкранного режима

В этой роли мы говорим, что всем нашим функциям разрешено выполнять любые действия в нашей таблице DynamoDB. Обратите внимание, что в целях тестирования я добавил действие dynamodb:*, не используйте его при работе с таблицей.

Если теперь вы снова развернете и запустите функцию POST, вы увидите, что у вас есть элемент в таблице DynamoDB.

Давайте извлечем конкретный элемент из нашей таблицы.

В папке src создайте новый файл под названием fetch.js и добавьте следующий код:

const AWS = require('aws-sdk')

const fetch = async (event) => {

    const dynamoDB = new AWS.DynamoDB.DocumentClient();
    const { id } = event.pathParameters;
    let todo;

    try {
        const result = await dynamoDB.get({
            TableName: 'TodoTable',
            Key: { id }
        }).promise();
        todo = result.Item;
    } catch (error) {
        console.log(error);
    };

    return {
        statusCode: 200,
        body: JSON.stringify(todo)
    };
};

module.exports = {
    handler: fetch
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь перейдите в файл serverless.yml и добавьте следующее в функцию add:

fetch:
    handler: src/fetch.handler
    events:
      - httpApi:
          path: /todo/{id}
          method: get

Войти в полноэкранный режим Выйти из полноэкранного режима

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

Выполните развертывание, и вы получите следующий результат:

Deploying aws-node-http-api-project to stage dev (eu-north-1)

✔ Service deployed to stack aws-node-http-api-project-dev (50s)

endpoints:
  POST - https://...execute-api.eu-north-1.amazonaws.com/
  GET - https://...execute-api.eu-north-1.amazonaws.com/todo/{id}
functions:
  add: aws-node-http-api-project-dev-add (2.3 kB)
  fetch: aws-node-http-api-project-dev-fetch (2.3 kB)
Вход в полноэкранный режим Выход из полноэкранного режима

Как вы видите, у нас есть две конечные точки и две функции. Теперь вы можете сделать следующее, чтобы получить доступ к определенному элементу в вашей таблице:

method: GET
endpoint: https://...execute-api.eu-north-1.amazonaws.com/todo/{id}
Войти в полноэкранный режим Выйти из полноэкранного режима

Развертывание

Последнее слово о развертывании, прямо сейчас мы внесли изменения в наш файл serverless.yml, поэтому нам нужно сделать sls deploy, что займет 1-2 минуты, но, допустим, вы внесли изменения только в файл add.js и хотите развернуть эти изменения, тогда достаточно сделать следующее, что займет пару секунд:

sls deploy -f add
Войти в полноэкранный режим Выйти из полноэкранного режима

Вышеуказанное развернет только эту функцию.

Резюме

IaaC — это хороший способ использовать подход, основанный на коде, который позволяет сделать больше за меньшее время. Существует множество различных провайдеров для использования IaaC, и это был один из примеров.

Любые комментарии, вопросы и обсуждения всегда приветствуются!

Оцените статью
devanswers.ru
Добавить комментарий