Есть много способов писать серверные приложения на многих языках. Есть много рамки, которые помогут нам построить сервер, такой как Голанг с 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 способа развертывания функций без сервеса.
Автоматическое развертывание
- Настройка триггера
- Первая задача заключается в том, чтобы обнаружить изменения в файлах и папках репо REPO и вернуть список. Здесь мы будем использовать GIT Commit Diff между током и последним коммитатом и использовать фильтр, который вернет только добавленные или обновленные файлы списка. Затем мы пройдем через каждый файл, собрав только уникальные имени папок и вернемся в качестве вывода.
После добавления сервиса без сервеса
Сервисы
Действие сборки напечатает что-то вроде ниже.Проверьте измененные файлы
Установите матрицу для сборки
- Далее мы создадим работу для каждого имени папки, используя матричную стратегию, как показано ниже.
- Теперь пришло время создавать и развернуть функцию. Пожалуйста, определите все переменные 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 }}
- Руководство по эксплуатации
Иногда мы хотим развернуть функцию вручную, или она может быть пропущена вышеупомянутым скриптом, мы можем развернуть его вручную, потому что развертывание оно более важно, чтобы найти проблему в то время.
Здесь мы пропустим шаг, чтобы определить файлы, используя git diff и возвращать папку. Мы можем напрямую зайти во имя функциональной папки и запустить команду развертывания, например. NPX Смертный развертыватель
Отказ
Для ручного развертывания мы возьмем имя функции в качестве ввода действий и развертывая конкретную функцию, а не развертывание вручную.
После этого мы будем использовать его на нашей работе, как показано ниже.
Руководство
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»