Розгортання NodeJs додатку на AWS Elastic Beanstalk за допомогою GitLab та Docker

текст перекладу
pic

розгортання nodejs додатка на AWS Elastic Beanstalk

Привіт, розробники!

За останні роки такі сервіси, як Heroku, Render та Firebase стали моїми основними хмарними платформами для створення та запуску веб-додатків. Я також використовував AWS, але в основному для зберігання та доступу до даних через S3 за допомогою їхніх API при створенні веб- або мобільних додатків.

Нещодавно я вирішив розгорнути веб-додаток на Beanstalk, використовуючи безперервну інтеграцію, і саме тут вступає в гру GitLab. Ця стаття описує кроки, налаштування та визначення конвеєрів для побудови додатка з безперервною доставкою на Beanstalk.

Передбачається, що ви знаєте:

Для тих, хто має намір реалізувати ці кроки, передбачається, що ви маєте базові знання з:

i. Express (Node framework),

ii. Принципи CI/CD і як працює Gitlab,

iii. Docker

iv. Git

Можливо, невелике знання консолі AWS буде корисним, але не обов'язковим, оскільки я поясню концепції, які будуть використовуватися тут. Тож давайте почнемо 🙂

  1. Створіть NodeJs додаток

Створіть нову директорію, де зберігатимуться ваші файли, і створіть файл package.json, який описує додаток та залежності. В даному випадку це буде лише Express. Я назву його bean-app (NB: Використовуючи Windows CMD)

mkdir bean-app  
cd bean-app  

type nul > package.json

Скопіюйте код нижче і вставте його у файл package.json, створений вище, а потім виконайте npm install, щоб встановити залежності, визначені у файлі.

{  
 "name": "bean_app",  
 "version": "1.0.0",  
 "description": "Мій додаток на Beanstalk",  
 "author": "Ваше ім’я",  
 "main": "index.js",  
 "scripts": {  
 "start": "node index.js"  
 },  
 "dependencies": {  
 "express": "^4.18.2"  
 }  
}
npm install

Створіть файл для нашого вхідного файлу “index.js” і скопіюйте туди наступний код. Цей код створює Express додаток. Щоб перевірити, виконайте node index.js у вашому терміналі.

type nul > index.js
const express = require('express')  
const app = express()  
const port = 8080  

app.get('/', (req, res) => {  
 res.send('Hello Beanstalk!')  
})  

app.listen(port, () => {  
 console.log(`слухаючи на порту ${port}`)  
})
node index.js

Знімок маршруту index:

pic

2. Створіть новий Gitlab проект:

Як уже було сказано, передбачається, що ви маєте базові знання Gitlab, тому створіть новий порожній GitLab проект. Можете назвати його beanstalk-app. Ось мої налаштування:

pic

Новий GitLab проект

Далі, ми додаємо наші файли проекту до репозиторію GitLab. Тут ми використовуємо git для коміту файлів. Ініціалізуємо основну гілку в проекті та додаємо віддалений репозиторій для нашого проекту. Використовуйте команди нижче, щоб завантажити наші файли:

git init --initial-branch=main  
git remote add origin https://gitlab.com/***************  
git add .  
git commit -m "Початковий коміт"  
git push -u origin main
  • Замініть зірочки вище на посилання вашого репозиторію GitLab

4. Створення додатку на AWS Beanstalk

Тепер, коли ми налаштували наш Express проект і GitLab проект, давайте також підготуємо додаток на Beanstalk на AWS для розгортання, використовуючи наступні кроки:

  • Створіть AWS Root акаунт. Якщо у вас вже є акаунт, ви можете увійти
  • Далі підготуємо нове середовище Beanstalk з необхідними налаштуваннями. Клацніть тут, щоб потрапити на головну сторінку Beanstalk, де ви побачите список створених середовищ.
    текст перекладу
    Натискайте кнопку створити нове середовище

pic

середовище Beanstalk

  • На наступній сторінці (Вибір рівня середовища), виберіть Web Server Environment та натисніть кнопку select
  • Далі, дайте вашому додатку назву, встановіть назву середовища та оберіть бажане ім’я домену для доступу до вашого додатка. Ось скріншоти моїх налаштувань нижче:

pic

налаштування назви додатку

pic

  • Далі, у розділі платформи, використовуйте налаштування, як показано на зображенні нижче. Як вже було сказано, ми будемо використовувати Docker. Docker дозволяє нам упакувати додаток з його середовищем та всіма залежностями в «коробку», що називається контейнером. На щастя, AWS Beanstalk має середовище Docker, яке дозволяє попередньо упаковувати наш додаток з необхідними залежностями і також запускати додаток в контейнері, використовуючи ці ізольовані залежності. Ми не будемо глибоко вивчати Docker, оскільки передбачається, що у вас уже є базові знання про Docker і як він працює.

pic

налаштування платформи

  • У розділі Код додатку, виберіть зразковий додаток, а потім натисніть налаштувати додаткові параметри.
  • Тут, прокрутіть до розділу Мережа і натисніть на редагування. Змініть налаштування, як показано нижче:

pic

зміна мережі інстансу

Коли ми створюємо новий додаток на Beanstalk, автоматично створюється інстанс AWS EC2 для цього додатку. Інстанс EC2 можна порівняти з віртуальним сервером, що має кілька інфраструктур AWS, де розміщується та запускається наш додаток. На зображенні вище ми запускаємо наше середовище в Virtual Private Cloud з за замовчуванням налаштуваннями. Також ми призначаємо публічну IP-адресу для інстансу в створеному середовищі.

  • Нарешті, натискайте кнопку зберегти, а потім натискайте створити середовище
  • Почекайте кілька хвилин, поки ваше середовище для додатка буде налаштоване

pic

створення середовища Beanstalk

  • Після завершення створення, наша панель керування виглядатиме так

pic

панель керування Elastic Beanstalk

Коли середовище Elastic Beanstalk створюється, як видно на зображенні вище, воно запускає середовище з наступними ресурсами:

Запускається середовище з іменем GettingStartedApp-env з такими ресурсами AWS:

  • Інстанс Amazon Elastic Compute Cloud (Amazon EC2) (віртуальна машина) — на якому розміщується наш додаток
  • Група безпеки Amazon EC2
  • Бакет Amazon Simple Storage Service (Amazon S3) — де ми будемо зберігати ресурси додатка, такі як різні версії. Важливо зазначити, що бакет S3 не створюється для кожного додатка Beanstalk, а для кожного нового регіону, який ви використовуєте.
  • Тригери Amazon CloudWatch
  • Стек AWS CloudFormation
  • Доменне ім’я — через яке ми отримуємо доступ до нашого додатка

Чудово! Ми успішно налаштували додаток Beanstalk, і наш створений додаток доступний за доменом, який ми створили під час налаштування, і який також можна побачити на панелі середовища.

Далі ми налаштуємо наші конвеєри Gitlab.

  1. Будування та розгортання з Gitlab CI

У кореневій папці нашого express-додатка створіть файл .gitlab-ci.yml. Як передбачається, ми вже знаємо, що при розгортанні нашого проекту в Gitlab CI, система автоматично перевіряє цей файл і виконує всі конвеєри, які ми в ньому визначили.
текст перекладу
Скопіюйте наступний код і вставте його у файл, який ми створили.

image: node  

stages:  
 - build  
 - run  

variables:  
 APP_NAME: ${APP_NAME}  
 APP_VERSION: "1.0.0"  
 S3_BUCKET: "elasticbeanstalk-us-east-1-**********"  
 AWS_REGION: ${AWS_DEFAULT_REGION}  
 AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}  
 AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}  
 AWS_PLATFORM: Docker  
 ENV_NAME: ${ENV_NAME}  
 SSH_KEY: ${SSH_KEY}  

create_app_version:  
 stage: build  
 image: python:latest  
 allow_failure: false  
 script: |  
 pip install awscli #Встановіть інструменти awscli  

 echo "Створення нового zip файлу"  
 python zip.py ${APP_NAME}  

 echo "Створення нового мітки AWS версії"  
 AWS_VERSION_LABEL=${APP_NAME}-${APP_VERSION}-${CI_PIPELINE_ID}  
 S3_KEY="$AWS_VERSION_LABEL.zip"  

 echo "Завантаження версії в бакет"  
 aws s3 cp ${APP_NAME}.zip s3://${S3_BUCKET}/${S3_KEY} --region ${AWS_REGION}  

 echo "Створення нової версії додатку"  
 aws elasticbeanstalk create-application-version \  
 --application-name ${APP_NAME} \  
 --version-label $AWS_VERSION_LABEL \  
 --region ${AWS_REGION} \  
 --source-bundle S3Bucket=${S3_BUCKET},S3Key=${S3_KEY} \  
 --description "${CI_COMMIT_DESCRIPTION}" \  
 --auto-create-application \  
 only:  
 refs:  
 - main  

deploy_app_version:  
 stage: run  
 image: coxauto/aws-ebcli  
 when: manual  
 script: |  
 AWS_VERSION_LABEL=${APP_NAME}-${APP_VERSION}-${CI_PIPELINE_ID}  

 echo "Розгортання додатку"  
 eb init -i ${APP_NAME} -p ${AWS_PLATFORM} -k ${SSH_KEY} --region ${AWS_REGION}  
 eb deploy ${ENV_NAME} --version ${AWS_VERSION_LABEL}   
 only:  
 refs:  
 - main

У наведеному коді ми визначили наші Gitlab Pipelines з двома етапами "build" і "run". Ми також створили два завдання, "create app version" та "deploy app version". Спочатку розглянемо змінні, які ми визначили, пояснимо кожну з них, а також заповнимо різні поля в налаштуваннях Gitlab. Значення змінних будуть заповнені, коли проект буде запущений.

Маленька примітка: При додаванні змінних середовища в GitLab, зніміть галочку з опції захищеної змінної. Якщо ця опція увімкнена, вона експортує змінні тільки для захищених гілок.

  • APP_NAME: Я встановив цю змінну для збереження імені додатку на Elastic Beanstalk, яке ми створили раніше. Створіть нову змінну середовища в GitLab з ключем APP_NAME та встановіть значення як ім’я додатку на Beanstalk. Як показано на скріншоті нижче:

pic

  • S3 BUCKET: Як вже згадувалося, коли створюється додаток Elastic Beanstalk, для регіону, де ви створюєте додаток, також створюється бакет s3. Ви можете використовувати цей бакет або будь-який інший бакет, до якого ви маєте доступ. Щоб використовувати бакет, пошукайте s3 в пошуковому рядку і натисніть на посилання s3, яке з’явиться.

pic

пошук s3

На панелі s3 скопіюйте ім’я вашого бажаного бакету та замініть його в файлі. Також переконайтеся, що регіон AWS відповідає регіону вашого додатку Beanstalk.

pic

  • AWS_REGION: Створимо змінну середовища GitLab і встановимо значення нашого регіону AWS на той, де ми створили наш додаток Beanstalk. У моєму випадку "us-east-1". У меню GitLab перейдіть до Settings>CI/CD. Розкрийте розділ змінних і додайте свій ключ як AWS_REGION, а для значення вкажіть регіон.
  • AWSACCESSKEYID і AWSSECRETACCESSKEY: Щоб отримати наші ключі доступу до AWS, створюємо нового користувача IAM. Використовувати облікові дані кореневого користувача організації є порушенням безпеки і не рекомендується. Для створення нового користувача IAM, на панелі меню натискаємо на назву організації і в випадаючому меню вибираємо security credentials.
    текст перекладу
    Натисніть на посилання Users в меню зліва на сторінці, а потім на кнопку add users.

pic

сторінка користувачів

На наступній сторінці введіть ваше ім’я. Вам не потрібно включати доступ до консолі для цього користувача, оскільки нам лише потрібен ключ доступу та секрет для цього користувача. Натисніть Next для налаштування дозволів, потім виберіть attach policy directly і під Permissions policies виберіть Administrative Access. Натисніть кнопку Next та потім Create User.

pic

новий користувач

Після створення нового користувача, ви будете перенаправлені на список користувачів. Натисніть на нового користувача, якого ви створили, і на сторінці користувача натисніть на вкладку Security Credentials.

pic

дані для безпеки

Далі на цій вкладці знайдіть розділ Access Keys і натисніть на кнопку create access key. На сторінці створення під розділом Access key best practices & alternatives виберіть Command Line Interface.

pic

Додайте опис (необов’язково), а потім натисніть кнопку create access key. Чудово! Тепер ми бачимо наш ключ доступу та секретний ключ доступу, які були створені для цього користувача. Створіть відповідні змінні середовища GitLab з ключами, зазначеними вище, і скопіюйте значення Access Key до AWSACCESSKEY_ID та Secret access key до AWSSECRETACCESS_KEY.

pic

  • AWS_PLATFORM: Як ми налаштували під час початкової конфігурації нашого проекту на Beanstalk, ми будемо використовувати Docker.
  • ENV_NAME: Створіть нову змінну середовища GitLab з кроками, зазначеними в AWSREGION, але в цьому випадку використовуйте **ENVNAME** як ключ. Значенням буде ім’я середовища вашого додатку на Beanstalk, як показано нижче.

pic

середовище Beanstalk

  • SSH_KEY: Цей ключ буде використовуватися як частина аргументів для розгортання нашого додатку на EC2 інстансі, який було створено разом з додатком Beanstalk. Щоб отримати цей ключ, пошукайте EC2 у пошуковому рядку та натисніть на посилання EC2. На панелі EC2, під розділом resources, натисніть на посилання key pairs, щоб створити ваш ключ. Ви також можете переглянути ваші працюючі інстанси, натиснувши на посилання Instances(running).

pic

На сторінці натисніть на кнопку create key pair, а на формі введіть назву для вашого ключа і можете залишити інші налаштування без змін. Натисніть create pair.

pic

Створіть нову змінну середовища GitLab під назвою SSH_KEY і призначте їй значення назви ключа, який ви створили вище. І це все для змінних Pipeline. Тепер давайте подивимося, що відбувається в двох завданнях, які ми додали.

  • Job 1: createappversion:

Це завдання буде виконуватися на етапі побудови нашого pipeline. Ми будемо використовувати останній Docker образ Python для написання скрипта, який створить нашу нову версію додатку. Існує доступний Docker образ AWS, який можна було б використати, але ми використовуємо Python, тому що він дозволить нам заархівувати нашу директорію проекту та завантажити її в S3 бакет для використання нашим додатком Beanstalk.

У нашому скрипті ми встановлюємо різні інструменти AWS, які нам знадобляться для роботи в нашому Python shell. Далі ми створюємо Python файл під назвою zip.py в корені нашого проекту, який буде використовувати бібліотеку shutil для архівування нашого додатку. Вставте наступний код в щойно створений файл.

import sys, shutil  
shutil.make_archive(sys.argv[1], 'zip', '.')

Далі, використовуючи наші визначені змінні, ми завантажуємо створений zip файл в наш S3 бакет, використовуючи мітку версії, яку ми визначили.
текст перекладу
Нарешті ми створюємо версію додатку, використовуючи мітку, яку ми визначили, а також інші змінні, які ми створили. Щоб дізнатися більше про аргументи AWS Elastic Beanstalk, натисніть тут. Ми також зазначили, що це завдання буде виконуватись лише при коміті змін в основну гілку.

  • Завдання 2: deployappversion:

Це завдання буде виконуватися на наступному етапі (етап виконання) нашого pipeline. Тут ми використовуємо Docker-образ AWS Beanstalk для написання скрипта, який розгорне версію додатку, створену на етапі побудови, на нашому середовищі Beanstalk. Спочатку ми встановлюємо значення за замовчуванням для додатку Beanstalk, на який ми його розгортаємо, а потім, вказавши версію додатку, яку ми хочемо використовувати (в даному випадку ту, що ми створили на етапі побудови), ми розгортаємо версію на середовищі Beanstalk. Щоб дізнатися більше про аргументи EB CLI, натисніть тут. Як і в першому завданні, ми також будемо запускати це завдання тільки при коміті змін в основну гілку.

4. Створення Docker файлу

Четвертий крок — створення Docker файлу, який буде виконуватись, коли наш додаток буде розгорнуто на нашому інстансі. У кореневій директорії вашого проекту створіть файл Dockerfile і вставте наступний скрипт у файл.

FROM node:16  

# Створення директорії додатку  
WORKDIR /usr/src/app  

# Встановлення залежностей додатку  
# Використовуємо wildcard для того, щоб скопіювати як package.json, так і package-lock.json  
# де вони доступні (npm@5+)  
COPY package*.json ./  

RUN npm install  
# Якщо ви будуєте код для продакшн  
# RUN npm ci --only=production  

# Створення джерела додатку  
COPY . .  

EXPOSE 8080  
CMD ["node", "index.js"]

Це має бути досить зрозуміло, якщо ви знайомі з Docker. Якщо ні, ви можете прочитати більше про це тут. Знову ж таки, припускається, що у вас є базові знання Docker.

Також створіть файл .dockerignore у кореневій директорії вашого проекту і додайте наступне:

node_modules  
npm-debug.log

5. Комітуємо наші зміни

Нарешті, давайте закомітимо наші зміни та побачимо, як наш pipeline працює на GitLab. Запустіть наступну команду в терміналі для коміту всіх змін (сподіваюся, ви все ще на основній гілці).

git add .  
git commit -m "updated pipelines"  
git push origin main

Якщо все пройде чудово, перше завдання має пройти успішно, і як ми зазначили в нашому pipeline, друге завдання буде ініційоване вручну. Посилання на зображення нижче:

pic

pipeline passed

Далі натисніть кнопку відтворення на другому завданні, щоб розгорнути наш додаток на нашому інстансі Beanstalk. Якщо проблем не виникне, друге завдання також повинно пройти. Якщо виникнуть помилки, натисніть на завдання, щоб переглянути логи і виправити зазначену помилку.

Натисніть на посилання додатку Beanstalk, і якщо наше розгортання буде успішним, на сторінці ми побачимо "Hello Beanstalk". В іншому випадку можна перевірити логи додатку, щоб зрозуміти, що могло піти не так.

pic

І ось і все! Наш додаток успішно розгорнуто на AWS Elastic Beanstalk. За допомогою нашого Pipeline ми можемо безперервно вносити зміни до нашого додатку та також повертатися до старих версій, коли забажаємо. Не соромтеся досліджувати панель управління вашим новим розгорнутим додатком.

Це було довго! Час на каву 🙂

Перекладено з: Deploying a NodeJs app on AWS Elastic Beanstalk using GitLab and Docker

Leave a Reply

Your email address will not be published. Required fields are marked *