Рубрики
Uncategorized

Настройка CI / CD для приложения MonorePOPS через серверы на AWS с использованием действий GitHub

Есть много способов писать серверные приложения на многих языках. Есть много рамки, чтобы помочь … Помечено с помощью серверу, AWS, GitHub, CICD.

Есть много способов писать серверные приложения на многих языках. Есть много рамки, которые помогут нам построить сервер, такой как Голанг с MUX, Java с весенним загрузкой, Nodejs с Express и т. Д. Когда дело доходит до размещения сервера приложения и масштабирования системы, это требует много усилий, планирования. ServerLess — это модель развития облака, которая позволяет разработчикам создавать и запускать приложения без необходимости управления серверами. Таким образом, используя модель архитектуры без сервеса, нам не нужно беспокоиться о предоставлении программных расщеплений на обеспечении обеспечения для обеспечения обеспечения платсов, обновляя патчи безопасности, кто-то взхватывает наш сервер и гораздо больше. Все это позаботится по провайдеру облака. Таким образом, можно сказать, что мы должны пытаться использовать архитектуру без сердца для API, где это возможно.

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

AWS LAMBDA

AWS LAMBDA — это сервис Serverless Compute, который мы будем использовать для развертывания наших функций JS. Мы просто загружаем наш код в качестве ZIP-файла и лямбда автоматически и точно выделяемым вычислительной мощностью выполнения и запускает ваш код на основе входящего запроса или события, для любой масштабы трафика.

Есть много рамки, доступных для записи Nodejs Serverless Application, как Архитектор , Вверх , Среднее И многое другое. Мы будем использовать Смертная рамка Чтобы написать наше приложение BackeND API, потому что мы можем использовать несколько языков программирования, и мы будем использовать несколько других услуг AWS, такую как S3, Gateway API и Serverless Framework имеет нашу поддержку для него.

Смертные рамки

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

Настраивать

Предварительные условия

  • Nodejs:
  • Serverless CLI: Установка команды NPM Установить -G Serverless

Мы будем писать простое приложение Nodejs с помощью структуры ниже файла/папки, или вы можете запустить Смертный Команда и настроить новый проект из шаблона. Вы можете клонировать демо-код от https://github.com/thakkaryash94/aws-serverred-ci-cd-demo Отказ

.
├── handler.js
├── package-lock.json
├── package.json
└── serverless.yml

Handler.js.

'use strict';

module.exports.main = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Hello from new service A!',
        input: event,
      },
      null,
      2
    ),
  };
};

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

serverless.yml.yml.

service: servicea

frameworkVersion: "2"

provider:
  name: aws
  runtime: nodejs14.x
  lambdaHashingVersion: 20201221
  region: ${env:AWS_REGION}
  apiGateway:
    restApiId: ${env:AWS_REST_API_ID}
    restApiRootResourceId: ${env:AWS_REST_API_ROOT_ID}
  # delete below section if you don't want to keep the Lambda function zip in a bucket
  deploymentBucket:
    blockPublicAccess: true # Prevents public access via ACLs or bucket policies. Default is false
    skipPolicySetup: false # Prevents creation of default bucket policy when framework creates the deployment bucket. Default is false
    name: ${env:AWS_BUCKET_NAME} # Deployment bucket name. Default is generated by the framework
    maxPreviousDeploymentArtifacts: 10 # On every deployment the framework prunes the bucket to remove artifacts older than this limit. The default is 5

functions:
  main:
    handler: handler.main # Function name
    memorySize: 128
    events:
      - http:
          path: servicea # URL path to access the function
          method: get # Method name for API gateway

Теперь вы можете запустить команду ниже, чтобы выполнить функцию локально. Это даст вам предупреждение о пропущенных переменных средах, таких как AWS_REGION, AWS_BUCKET_NAME и т. Д., Но мы можем игнорировать их, или вы можете прокомментировать их, а также для местной цели развития.

$ serverless invoke local -f main

Это вернет ответ, как показано ниже.

{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Hello from new service A!\",\n  \"input\": \"\"\n}"
}

Таким образом, это означает, что наше неверное приложение готово и работает правильно локально. Для реального проекта нам понадобится многие из этих приложений. Таким образом, каждое приложение будет служить на индивидуальном запросе API.

Мы держим наш код на поставщиков VCS, как github, gitlab, bitbucket и т. Д. Проблема в том, что это будет очень сложно поддерживать много репозиториев, таких как ниже даже для одного проекта. Итак, чтобы исправить это, мы можем хранить все эти приложения в одном репозитории, и он будет называться MonoRepo. Это разница между MonoRepo и Multirepo.

Настройка monorepo.

Чтобы преобразовать наши серверу, нам просто нужно создать папку, например. AWS-Serverless-CI-CI-CD-DEMO и переместите службы папки внутри него. Теперь мы можем иметь столько функций, сколько нам нужно для нашего проекта, и все они будут в одном репозитории.

Окончательная общая структура будет выглядеть ниже.

aws-serverless-ci-cd-demo
├── README.md
├── servicea
│   ├── handler.js
│   ├── package-lock.json
│   ├── package.json
│   └── serverless.yml
└── serviceb
    ├── handler.js
    ├── package-lock.json
    ├── package.json
    └── serverless.yml

Мы будем использовать AWS Lambda, AWS S3 и Gateway API для развертывания и доступа к нашим услугам. Итак, давайте обсудим об использовании AWS S3 и Gateway API.

AWS S3.

Amazon Simple Storage (Amazon S3) — это служба хранения объектов, которая предлагает ведущую ведущую масштабируемость, доступность данных, безопасность и производительность.

Мы будем хранить наш код функции лямбда как ZIP в ведре. Преимущество в том, что мы можем поддерживать дорожку функций лямбда с кодом и дату. Это совершенно дополнительный шаг. Вы можете пропустить это, комментируя, удаляя Развертываниеbucket код в Serverless.yml файл.

AWS API Gateway

Gateway Amazon API — это полностью управляемая услуга, которая позволяет разработчикам создавать, публиковать, поддерживать, монитор и защищать API в любой масштабе. API API выступают в качестве «передней двери» для приложений для доступа к данным, бизнес-логике или функционалам из ваших бэкэндов.

Мы будем использовать Gateway API, чтобы открыть нашу функцию лямбда на URL, чтобы мы могли получить доступ к нему. Serverless Framework будет использовать путь , Метод от http . Раздел и маршрут настроек на основе этого. В демонстрации это создаст /ServieSea Маршрут с Получить метод. Serverless Framework составит этот маршрут с нашей функцией лямбда.

Развертывание CI/CD

«CI» в CI/CD относится к непрерывной интеграции, который является процессом автоматизации для создания, протестировал код, когда разработчики нажимают код. В нашем приложении создать ZIP-файл функций.

«CD» в CI/CD относится к непрерывной доставке и/или постоянному развертыванию, что означает доставку/развертывание кода к разработке, постановке, UAT, QA, производственной среде. В нашем приложении это означает развертывание функции zip to lambda и настроить Gateway API.

К счастью, Serverless Framework имеет встроенную поддержку для него. Таким образом, все, что нам нужно сделать, это доказать учетные данные AWS, как переменные среды, такие как AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESCE_KEY. Нам понадобится несколько переменных, потому что мы используем другие услуги, такие как S3 и Gateway API.

Мы будем использовать действия GitHub для создания, упаковки и развертывания наших функций. Итак, давайте посмотрим, как мы можем реализовать CI/CD с помощью действий GitHub.

Действия GitHub

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

Мы можем настроить действия GitHub на основе нескольких триггеров, как на толчок , pull_request и т. д. и согласно различным веткам.

Существует 2 способа развертывания функций без сервеса.

  1. Автоматическое развертывание

    1. Настройка триггера
    1. Первая задача заключается в том, чтобы обнаружить изменения в файлах и папках репо REPO и вернуть список. Здесь мы будем использовать GIT Commit Diff между током и последним коммитатом и использовать фильтр, который вернет только добавленные или обновленные файлы списка. Затем мы пройдем через каждый файл, собрав только уникальные имени папок и вернемся в качестве вывода.

    После добавления сервиса без сервеса Сервисы Действие сборки напечатает что-то вроде ниже.

    Проверьте измененные файлы

    Установите матрицу для сборки

    1. Далее мы создадим работу для каждого имени папки, используя матричную стратегию, как показано ниже.
    1. Теперь пришло время создавать и развернуть функцию. Пожалуйста, определите все переменные ENV, используемые в файле ServerLess.yml в разделе ENV, как показано ниже. Так вот вот, мы пройдемся через каждую папку и бегу NPX Смертный развертыватель Отказ Эта команда создаст ZIP, обновит его на S3, создайте/обновит лямбда и, наконец, настроив его с помощью шлюза API.

    Прежде чем нажать код и действие, начните создавать и развернуть код, нам нужно добавить ниже переменные секретной среды. Вы никогда не должны использовать root Account и всегда создаю новый пользователь с ограниченными разрешениями на основе случаев использования. В этом процессе наш пользователь понадобится доступ к Lambda, S3 Access Access и API Gateway.

  - AWS_ACCESS_KEY_ID
  - AWS_SECRET_ACCESS_KEY
  - AWS_REGION
  - AWS_REST_API_ROOT_ID
  - AWS_REST_API_ID
  - AWS_BUCKET_NAME: bucket name where we want our zip files to be stored, if you are ignoring `deploymentBucket` from `serverless.yml` file, you can ignore this variable as well.

auto.yml.

name: Auto Serverless Deployment
on: [push, pull_request]

jobs:
  changes:
    name: Changes
    runs-on: ubuntu-latest
    outputs:
      folders: ${{ steps.filter.outputs.folders }}
    steps:
      - uses: actions/checkout@v2
      - name: Check changed files
        id: diff
        run: |
          if [ $GITHUB_BASE_REF ]; then
            # Pull Request
            git fetch origin $GITHUB_BASE_REF --depth=1
            export DIFF=$( git diff --name-only origin/$GITHUB_BASE_REF $GITHUB_SHA )
            echo "Diff between origin/$GITHUB_BASE_REF and $GITHUB_SHA"
          else
            # Push
            git fetch origin ${{ github.event.before }} --depth=1
            export DIFF=$( git diff --diff-filter=d --name-only ${{ github.event.before }} $GITHUB_SHA )
            echo "Diff between ${{ github.event.before }} and $GITHUB_SHA"
          fi
          echo "$DIFF"
          # Escape newlines (replace \n with %0A)
          echo "::set-output name=diff::$( echo "$DIFF" | sed ':a;N;$!ba;s/\n/%0A/g' )"
      - name: Set matrix for build
        id: filter
        run: |
          DIFF="${{ steps.diff.outputs.diff }}"

          if [ -z "$DIFF" ]; then
            echo "::set-output name=folders::[]"
          else
            JSON="["
            # Loop by lines
            while read path; do
              # Set $directory to substring before /
              directory="$( echo $path | cut -d'/' -f1 -s )"

            # ignore .github folder
            if [[ "$directory" != ".github" ]]; then
              # Add build to the matrix only if it is not already included
              JSONline="\"$directory\","
              if [[ "$JSON" != *"$JSONline"* ]]; then
                JSON="$JSON$JSONline"
              fi
            fi
            done <<< "$DIFF"

            # Remove last "," and add closing brackets
            if [[ $JSON == *, ]]; then
              JSON="${JSON%?}"
            fi
            JSON="$JSON]"
            echo $JSON

            # Set output
            echo "::set-output name=folders::$( echo "$JSON" )"
          fi
  deploy:
    needs: changes
    name: Deploy
    if: ${{ needs.changes.outputs.folders != '[]' && needs.changes.outputs.folders != '' }}
    strategy:
      matrix:
        # Parse JSON array containing names of all filters matching any of changed files
        # e.g. ['servicea', 'serviceb'] if both package folders contains changes
        folder: ${{ fromJSON(needs.changes.outputs.folders) }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
      - name: deploy
        run: npx serverless deploy
        working-directory: ${{ matrix.folder }}
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REST_API_ROOT_ID: ${{ secrets.AWS_REST_API_ROOT_ID }}
          AWS_REST_API_ID: ${{ secrets.AWS_REST_API_ID }}
          AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME }}
  1. Руководство по эксплуатации

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

Здесь мы пропустим шаг, чтобы определить файлы, используя git diff и возвращать папку. Мы можем напрямую зайти во имя функциональной папки и запустить команду развертывания, например. NPX Смертный развертыватель Отказ

  1. Для ручного развертывания мы возьмем имя функции в качестве ввода действий и развертывая конкретную функцию, а не развертывание вручную.

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

Руководство

name: Manual Serverless Deployment
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:
    inputs:
      function:
        description: "Function name"
        required: true
jobs:
  deploy:
    if: ${{ github.event_name == 'workflow_dispatch' }}
    name: deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: deploy
        run: npx serverless deploy
        working-directory: ${{ github.event.inputs.function }}
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REST_API_ROOT_ID: ${{ secrets.AWS_REST_API_ROOT_ID }}
          AWS_REST_API_ID: ${{ secrets.AWS_REST_API_ID }}
          AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME }}

Здесь мы увидели, как мы можем настроить авто, ручное развертывание для сервера без сервера с CI/CD.

Ссылки:

Оригинал: «https://dev.to/thakkaryash94/setup-ci-cd-for-serverless-monorepos-application-on-aws-using-github-actions-33hi»