Розгортання проєкту на AWS: практичний гайд для новачків

Якщо ви помітили, знання AWS нині стали одною з головних вимог не лише для DevOps-інженерів, Cloud-інженерів, а й для більшості розробників. Особливо, якщо мова йде про backend розробку, яка вже давно виходить за межі лише написання коду.

В цій статті не буде складних, максимально безпечних і до деталей продуманих архітектурних рішень, що зазвичай використовуються для великих проектів. Це здебільшого мануал з мого особистого досвіду для тих девелоперів, хто робить перші кроки у взаємодії з AWS і хоче навчитися розгортати там свій проект. Сподіваюся, ви вже освоїли базову теоретичну частину, а тому не буду описувати, що таке EC2, VPC, RDS, ElastiCache тощо. Якщо вас цікавить саме базова частина, то пропоную подивитися курс Introduction to AWS на 3 години або навіть Ultimate AWS Certified Cloud Practitioner CLF-C02 на 15, якщо в майбутньому хочете вийти на сертифікацію. Трохи жартівливо-лякаючого контенту не завадить:

Для розгортання я обрала один зі своїх відносно недавніх проектів, пов’язаних з вивченням граматики англійської мови. Він складається з двох частин: API (EnGram_async), яке бере граматичні тести з бази даних, правильно обробляє їх та повертає, і телеграм бота (EnGram_bot), який ці тести відображає користувачеві. Описані частини мали розташовуватися окремо і незалежно один від одної, щоб в перспективі до API можна було підключити будь-який фронтенд та що завгодно інше.

Не сумніваюся, процес розгортання можна організувати простіше, ніж зробила я, однак для того, щоб максимально відтренувати роботу з різними сервісами, та інструментами AWS, я використала два сервери EC2, одне RDS та два ElastiCache. До того ж мені знадобилося дві VPC з налаштованим VPC Peering між ними.

Щодо тарифів: в мене зараз доступний Free Tier і я максимально намагалася вписатися в його умови. Звичайно, були нюанси, за які в мене списало кошти, але я про них розповім дещо пізніше. Тим не менш, мова йшла про 1 долар максимум, що не є для мене шаленою втратою.

Важливий момент: для розгортання всього необхідного обирала найближчу до себе локацію (я працюю в Києві), а саме Europe (Frankfurt). Якщо обрати щось інше, то можна почати втрачати кошти на рахунку, тому пропоную вам бути уважними.

Налаштування RDS

Починала я з налаштування бази даних, а точніше – з налаштування інстансу для неї, оскільки створити інстанс на RDS не обов’язково означає створення бази даних там: для цього доведеться зробити ще кілька кроків. Натискаємо на Create Database у розділі RDS:

І далі потрапляємо на сторінку з налаштуваннями, де потрібно обрати всі необхідні параметри для створення.

В рамках Free Tier RDS може бути безкоштовним, якщо ви вписуєтеся у норми, описані за посиланням Amazon RDS Free Tier

Тобто вам доступно 750 годин на місяць на всі інстанси разом і при цьому ви отримаєте певні обмеження на тип інстансу, тип бази, розмір тощо. Я не мала намір відхилятися від Free Tier і мій проект чудово вписався в необхідні рамки: при створенні RDS я обрала тип бази MySQL, класс db.t4g.micro, місткість 20 GiB.

Дані на сторінці налаштування інстансу RDS я вносила по-мінімуму, лишаючи якнайбільше дефолтних значень. Однак майте на увазі, що незаповнення розділу Additional configuration призведе до того, що база даних не створиться і це доведеться робити вручну. Я благополучно забула заповнити даний розділ, а тому потім сиділа гралася зі створення БД, що опишу нижче (раптом знадобиться).

Я також обирала «Don’t connect to an EC2 compute resource», оскільки поки що ми не маємо EC2. Так само я не створювала нове VPC, а взяла дефолтне, яке вже має достатньо потрібних нам налаштувань. Після створення RDS необхідно трохи зачекати, поки статус інстансу стане Available. Ви можете вимикати інстанс на той час, коли ним не користуєтеся (Actions – Stop temporarily), щоб ці години не враховувалися у 750 годин, які вам дали на місяць. Проте майте на увазі наступний цікавий і важливий факт:

Тобто через 7 днів сервіс підніметься знову, а тому його доведеться знову вимкнути, або краще навіть видалити, якщо не потрібен.

Створення EC2.

До нашого RDS ми ще повернемося, а зараз перейдемо до створення EC2 і далі ви зрозумієте, чому.

Після натискання Launch Instance на сторінці EC2 перед нами відкриється вікно налаштувань. Там я обрала стандартне AMI (Amazon Linux 2023 AMI), Instance type – t2.micro, а також створила новий Key Pair – він знадобиться нам, щоб підключатися до EC2 зі свого комп’ютера. Важливо цей ключ зберегти кудись в надійне місце. У Security розділі залишила галочку біля Allow SSH traffic from, проте Anywhere замінила на My IP. Все інше лишила як є.

Далі після натискання Launch Instance потрібно зачекати кілька хвилин, поки інстанс запуститься. Майте на увазі, що в рамках Free Tier вам також надається 750 безкоштовних годин на місяць для всіх інстансів, тому краще зупиняйте свій інстанс на той час, поки не користуєтеся ним, а то буде як у мемі:

Якщо ви помітили, тип інстансу та AMI я обирала такі, щоб це також вписувалося в рамки безкоштовного тарифу.

Підключення EC2 до Visual Studio Code.

Пишучи код, я користуюся Visual Studio Code (далі VSC). Ви можете використовувати будь-що інше – важливо відкрити термінал bash для того, щоб підключитися до EC2 зі свого комп’ютера. Для чого нам таке підключення? Щоб закинути на новостворений сервер свій код. Зокрема, код для API, який генерує граматичні тести.

Почнемо зі встановлення розширення для VSC під назвою Remote – SSH. Тут, думаю, все просто.  

Далі, знаходячись у VSC, натискаємо Ctrl+Shift+P (або Cmd+Shift+P на Mac) – зверху з’являться пропозиції для вибору. Там прописуємо і обираємо Remote-SSH: Add New SSH Host.

VSC запропонує ввести адресу, де потрібно прописати наступне:

 ssh -i "path/to/your-key.pem" ec2-user@your-ec2-public-ip

де path/to/your-key.pem – це шлях до ключа, який ми собі зберегли під час створення EC2, а your-ec2-public-ip – це публічна адреса нашого EC2, яку можна дізнатися наступним чином:

Не зважайте на те, що в мене ця адреса порожня – вона зникає, якщо інстанс має статус Stopped. Якщо інстанс активний, її можна побачити і скопіювати.

Далі VSC запропонує зберегти дане налаштування у файлі конфігурації. Це зазвичай папка .ssh, яка знаходиться у папці вашого облікового запису на комп’ютері. Наприклад C:\Users\UserName\.ssh. Саме туди буде записано файлик config, який ми час від часу редагуватимемо. На початку він має вигляд:

де Host та HostName – це публічна адреса EC2.

Однак Host та HostName після кожного перезапуску інстансу доведеться змінювати, оскільки змінюватиметься його Public IPv4 address. Якщо не хочете з цим гратися, можна створити Elastic IP: воно закріпиться за інстансом назавжди. Але тоді вам доведеться платити за нього кошти – це саме те, за що в мене їх списало. Сума була невеликою, але я все-таки вирішила відключити Elastic IP.

Важливе зауваження: зберігати всі файли, з якими ми будемо взаємодіяти під час налаштування, наповнення нашого серверу, дуже бажано у папках, що у своїй назві не містять кирилиці і пропусків. Тобто з папкою в форматі C:\Users\Вася Петренко\.ssh, на жаль, можуть виникнути труднощі.

Щоб підключитися до EC2, вам потрібно знову натиснути Ctrl+Shift+P, але цього разу обрати Remote-SSH: Connect to Host і той хост, який вказано у файлі config. Тут я зрозуміла, що процес підключення до EC2 не такий легкий, як здається.

По-перше, виникли проблеми з доступом до ключа .pem через неправильно вказаний шлях. Тут вам доведеться погратися самостійно, оскільки я не знаю, де саме ви його зберігаєте. Переконайтеся, що ваш ключ в тому місці, яке ви вказали у config файлі. Плюс зверніть увагу на пропуски і кирилицю у назві папок.

По-друге, система написала, що ключ .pem має занадто відкриті права доступу. Є варіант самостійно вручну через інтерфейс Windows зменшити ці права. Але можна то зробити через PowerShell, яку необхідно запустити від імені адміністратора. Там послідовно внести наступні команди:

icacls "disc:\ path\to\your-key.pem" /inheritance:r 
icacls " disc:\ path\to\your-key.pem" /grant:r username:F

де disc:\ path\to\your-key.pem – шлях до вашого ключа (той що ви вказали в config файлі), а username – назва вашого облікового запису на віндовс.

Більше ніяких проблем я не зустрічала і мій VSC успішно підключився до EC2. Ось як це відбулося:

Встановлення всього необхідного на EC2.

Задача полягала в тому, щоб після підключення до серверу встановити там пайтон, клонувати репозиторій з git і створити віртуальне середовище. Тобто все те саме, що ми зазвичай робимо у себе на комп’юторі, коли пишемо код, створюється тепер на сервері і має запускатися там.

Кроки (а точніше команди в терміналі bash VSC) виглядали так:

1) Встановлення Python і pip:

sudo yum install python3-pip -y 

2) Встановлення Git:

sudo yum install git -y

3) Клонування репозиторію:

git clone https://github.com/yahrdev/EnGram_async.git

4) Перехід у папку проекту:

cd EnGram_async

5) Відкриття цього проекту у лівому вікні для того, щоб можна було бачити паки і файли:

code . --reuse-window

6) Створення віртуального середовища:

python3 -m venv Envenv

7) Його активація:

source Envenv/bin/activate

8) Встановлення всіх бібліотек та модулів:

pip install -r requirements.txt

В результаті картинка виглядала приблизно так:

Здавалося б, тепер можна просто запускати свій додаток і все запрацює. Проте мій проект містить базу даних і кеш, без яких API навіть не запуститься, а тому доведеться повернутися до створення та налаштування бази даних, а також всіх необхідних конфігурацій і конекшенів.

Скажу одразу, щоб не затягувати: мені довелося редагувати деякі файли проекту прямо на сервері через VSC. Цього краще не робити, однак всяке буває. В результаті, мій інстанс досягав 100% CPU від, здавалося б, найпростіших дій. Я зберігала файл через VSC – все зависало, VSC починало заново перепідключатися до EC2 , але так ніколи і не поверталося «до життя», поки я не зупиняла і заново не стартувала інстанс. Дослідження показало, що виною тому було автоматично встановлене розширення Pylance для VSC. Воно кожен раз, коли я змінювала код, йшло перевіряти зміни і, скоріш за все, перевантажувало систему. Лише тільки налаштування в стилі

{
    "python.analysis.diagnosticMode": "openFilesOnly",
    "python.analysis.typeCheckingMode": "off", 
    "python.analysis.autoSearchPaths": false,
    "python.analysis.useLibraryCodeForTypes": false,
    "python.languageServer": "Pylance"
}

які я помістила у файл settings.json мого проекту, не допомогли. Що я зробила? Видалила Pylance на сервері і все заспокоїлося. Тому раджу максимально уникати встановлення Pylance на ваш сервер і писати весь свій код спочатку локально у себе на комп’ютері.

Створення бази на RDS  та налаштування конекшену з EC2.

Почнемо ми саме з конекшену: для цього необхідно повернутися до RDS і перейти в його секюріті групу:

В цій групі потрібно додати нове inbound rule з наступними правилами:

  • Type: MySQL/Aurora
  • Protocol: TCP
  • Port Range: 3306
  • Source: Security Group нашого EC2 (API).

І зберегти зміни

Тепер наше EC2 зможе ходити за даними в базу, яка буде знаходитися на RDS, хоча поки її там немає і тепер доведеться додати. Для цього деактивуємо наше віртуальне середовище через команду deactivate і через cd повернемося до початкової папки серверу. Далі – зробити наступні кроки:

1) Стати супеюзером:

sudo su –

2) Встановити репозиторій mysql:

dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-4.noarch.rpm

3) Встановити клієнта mysql:

dnf -y install mysql mysql-community-client

4) І тепер можна підконектитися до нашого RDS за допомогою команди:

mysql -h your-database-instance.rds.amazonaws.com-u admin –p

Система запропонує ввести пароль: це саме те значення, яке ви придумували на етапі створення RDS. Не лякайтеся, що під час набору паролю на клавіатурі у терміналі нічого не прописується: AWS так захищає нас від того, щоб хтось побачив навіть кількість знаків паролю. В результаті, якщо з конекшенами все добре, у терміналі має з’явитися наступне:

Саме тут ми внесемо наступні команди:

1) Створення бази даних:

CREATE DATABASE engram_async;

2) Перевірка, які бази є в наявності:

SHOW DATABASES;

3) Створення користувача з логіком і паролем (я ставила той пароль, що і для admin):

CREATE USER 'yahr'@'%' IDENTIFIED BY 'password';

4) Гарантування прав новому користувачеві:

GRANT ALL PRIVILEGES ON engram_async.* TO 'yahr'@'%';

Після усіх цих дій можна ввести exit для виходу з терміналу mysql.

Знову забудемо про RDS на деякий час, а потім повернемося до нього, оскільки необхідно зробити кілька проміжних кроків перед там, як наповнювати нашу базу даними.

Міграція Alembic.

Я є прихильником такої бібліотеки, як Alembic: вона дозволяє створювати таблиці в базі даних, використовуючи пайтонівський код. Також можна контролювати версії своїх змін, не виходячи з середовища розробки, і відкатувати їх, коли потрібно.

Мій проект влаштовано таким чином, що всі важливі паролі, адреси, токени тощо зберігаються у файлі .env. Також є файл config.py, що завантажує ці дані з .env і в результаті їх можна безпечно використовувати всюди у своїй програмі:

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    DB_USER: str
    DB_PASS: str
    DB_HOST: str
    DB_NAME: str
    DB_PORT: int
    MODE: str
    CACHE_REDIS_HOST: str
    CACHE_REDIS_PORT: int
    CACHE_REDIS_DB: int
    CACHE_TYPE: str
    CACHE_DEFAULT_TIMEOUT: int  #ttl for cache
    CACHE_KEY_PREFIX: str
    CACHE_CHECK_TIMEOUT: int  #how frequently check the ttl of the cache
    NUMBER_OF_TESTS: int
    SERVER_HOST: str
    SERVER_PORT: int

    @property
    def DB_URL(self):
        return f"mysql+aiomysql://{self.DB_USER}:{self.DB_PASS}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
    

    model_config = SettingsConfigDict(env_file=".env", extra='allow')

settings = Settings()

Таким чином, для налаштування роботи API вже в нових умовах, де світом правлять EC2, RDS тощо мені достатньо змінити тільки .env файл, а все інше, як от, наприклад, адреса sqlalchemy.url  у файлі alembic.ini лишається тією самою:

sqlalchemy.url = mysql+aiomysql://%(DB_USER)s:%(DB_PASS)s@%(DB_HOST)s:%(DB_PORT)s/%(DB_NAME)s

У файл .env я внесла наступні зміни:

Наступним кроком стало виконання команди яка застосовує прописані міграції (які міграції? Як виглядають? Що вони роблять? Дивіться файл 2b12ec7d4cd1_database_creation.py у папці migrations/versions), а саме

alembic upgrade head 

Заповнення бази даних.

Знову повернемося до роботи над RDS для того, щоб наповнити її даними. Граматичні завдання з англійської для своєї тестової версії проекту я брала з ChatGPT. Тут можна розробити ще один мікросервіс, який тягнутиме дані з якогось джерела адекватним шляхом і записуватиме у базу сам, проте поки нас це не цікавить. Натомість, я створила файл з запитами до бази даних, які додають завдання в нашу систему. Приклад:

use engram_async;
# A1

SET FOREIGN_KEY_CHECKS = 0;
insert IGNORE into questions (level, question, correct_id, explanation)
values('A1', 'She _____ a doctor.', 2, 'The correct form is "is" for third person singular in present simple.');
SET FOREIGN_KEY_CHECKS = 1;

insert into options (question_id, option_id, option_text)
values(LAST_INSERT_ID(), 1, 'are');

insert into options (question_id, option_id, option_text)
values(LAST_INSERT_ID(), 2, 'is');

insert into options (question_id, option_id, option_text)
values(LAST_INSERT_ID(), 3, 'am');

Всі свої тести я розмістила у файл add_tests.sql в папці мого проекту на сервері і запустила наступну команду:

mysql -h your-database-instance.rds.amazonaws.com -u admin -p engram_async < add_tests.sql

Якщо все добре, звичайні sql запити в стилі SELECT * FROM questions; мають повернути якісь дані.

Створення і налаштування ElastiCache.

З ElastiCache довелося погратися відносно довго. Певний час було зовсім незрозуміло, чому при спробі підключитися до кешу перевантажується весь EC2 сервер і зв’язок з ним втрачається. Але про це розповім дещо пізніше.

ElastiCache знадобився для кешу на основі Redis, який активно використовується у моєму проекті. В сукупності інстанси цього сервісу є безкоштовними 750 годин на місяць, проте, на жаль, інстанс ElastiCache неможливо зупинити на певний час, як це зазвичай роблять з EC2 та RDS, а тому двох таких не вистачить на місяць – доведеться доплачувати або видаляти їх повністю.

Перейдемо до створення ElastiCache, обравши Redis OSS:

Тут відмінностей від дефолтних значень буде більше, особливо враховуючи намагання вміститися у тарифи Free Tier. На першому етапі обираємо Design your own cache, Cluster cache, Cluster mode: Disabled:

Прибираємо галочку біля Multi-AZ, а також обираємо Node type: cache.t2.micro, Number of replicas: 0:

Далі обираємо Create a new subnet group і створюємо підмережу спеціально для нашого ElastiCache. Цю підмережу я створила в тому ж VPC, де розміщені мої EC2 та RDS.

На наступній сторінці налаштувань (після натискання Next) потрібно лише прибрати галочку з Enable automatic backups, якщо кеш має право видалитися і це не створить проблем для додатку.

Після створення ElastiCache варто зайнятися налаштуванням security group для нього, де прописати доступ до кешу з нашого EC2. Вказати там необхідно наступні параметри:

де sg-0c1a22481d9f62645 – це security group нашого EC2.

Після створення групи потрібно додати її на новостворений ElastiCache через кнопку Modify.

Ну і, нарешті, для налаштування з’єднання з EC2 я внесла деякі зміни у файлик .env, який ми з вами вже нещодавно редагували:

далі почалися пригоди…. Одразу було складно вияснити, що саме не працює: я запускала додаток і через деякий час чомусь відвалювався конекшен до EC2. Для того, щоб перевірити, чи дійсно цей конекшен працює, я вносила у терміналі мого EC2 наступні команди:

nslookup Primary endpoint з ElastiCache

Це підтвердило, що DNS-ім’я Redis у внутрішню IP-адресу розв’язується правильно.

Також я виконувала перевірку доступності порту:

nc -zv Primary endpoint з ElastiCache 6379

Якщо цієї команди немає, то потрібно встановити:

sudo yum install -y nmap-ncat

У мене дані команди повертали інформацію, що все добре, однак проблема не вирішувалася. Після певного дослідження виявилося, що помилка була взагалі в коді, який я написала. Пов’язана вона зі змінами в бібліотеках і умовами новоствореного інстансу ElastiCache.

Справа в тому, що в асинхронній версії свого API я використовувала aioredis, однак нещодавно відбулися зміни і тепер для коректної роботи необхідно замість aioredis використовувати звичайну бібліотеку redis, але при цьому імпортувати з неї asyncio і потім звідти брати клієнта Redis. Крім того, створюючи ElastiCache, я лишила Encryption in transit: Enabled, а отже довелося додати параметр ssl до свого коду. Тепер оновлений код з файлу cache_utils.py  для роботи з кешем виглядає так:

import redis.asyncio as redis
redis_async = redis.Redis(
            host=settings.CACHE_REDIS_HOST,
            port=settings.CACHE_REDIS_PORT,
            socket_timeout=5,
            socket_connect_timeout=5, 
            ssl=True
        )

Як бачите, також я додала нові параметри socket_timeout та socket_connect_timeout для контролю часу очікування підключення та відповіді від Redis-сервера. Вони запобігають зависанню програми на невизначений термін. Лише коли внесла ці зміни, мій додаток почав працювати без проблем.

Як я його запускала? Знаходячись у віртуальному середовищі через термінал прописала команду

python3 /home/ec2-user/EnGram_async/api/app.py

і після цього отримала пропозицію від VSC відкрити своє API у браузері:

В браузері відкрився Swagger для перевірки ендпоїнтів:

Створення скрипту для автозавантаження API.

Як ви розумієте, в ідеалі наше API повинно постійно крутитися на EC2. Тобто під час запуску інстансу має автоматично запускатися додаток. Для цього нам потрібно буде написати файл з командами, які будуть спрацьовувати при старті системи. Код файлу виглядає наступним чином:

[Unit]
Description=EngApp
After=network.target

[Service]
User=ec2-user
WorkingDirectory=/home/ec2-user/EnGram_async
ExecStart=/home/ec2-user/EnGram_async/Envenv/bin/python3 /home/ec2-user/EnGram_async/api/app.py
Restart=always
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

В першому розділі файлу вказується, коли саме запускати наші команди, в другому – що саме запускати, а в третьому – що робити після перезавантаження.

Тепер, знаходячись в терміналі нашого EC2, необхідно запустити команду

sudo nano /etc/systemd/system/Engproject.service

Коли файл відкриється, туди потрібно вставити вище написаний код:

і зберегти зміни через кнопки Ctrl + X → Y → Enter.

Щоб застосувати зміни, запустимо:

sudo systemctl daemon-reload

Далі запустимо сервіс через

sudo systemctl start Engproject

Ну і, нарешті, зробимо так, щоб після перезапуску EC2 сервіс запускався сам:

sudo systemctl enable Engproject

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

sudo systemctl status Engproject

Це був останній крок у налаштуванні роботи API. Дорога виявилася довгою і дещо тернистою, однак, сподіваюся, для вас вона була вже легшою, ніж для мене.

Налаштування телеграм боту.

Для другої частини проекту, а саме для телеграм боту, мені знадобилося окреме VPC, новий інстанс EC2 та ще один інстанс ElastiCache. Хотілося максимально ізолювати бот від API, оскільки ці проекти писалися, як окремі одиниці.

Я вже не буду розписувати детально процес створення нового інстансу EC2. Проте цього разу для створення доведеться провести деяку підготовчу роботу в розділі VPC, яку нам не потрібно було проводити раніше, оскільки ми використовували дефолтне VPC. На жаль, робота ця трошки заплутана, як для новачка, проте цілком по силам. Отже кроки:

1) Створити нове VPC. Тут лишала значення за замовченням.

2) У цьому VPC створити новий subnet і потім його відредагувати, вказавши Auto-assign public IPv4 address = Yes. Так, публічна IP адреса. Для тестових та навчальних цілей нам підійде (хоча це не зовсім правильно з точки зору безпеки, архітектури тощо), тим більше ми додамо секюріті групу з певними правами.

3) Створити Internet Gateway (IGW) і прив’язати його до свого VPC.

4) Налаштувати окремий Route Table, додавши до нього маршрут для 0.0.0.0/0 і направити його через Internet Gateway:

Далі можна приступати до створення EC2, але при цьому варто не забути обрати новостворені VPC та Subnet, а також створити нову security group з уже знайомими нам правилами, які дозволяють підключатися до EC2  з нашого комп’ютера:

Схема підключення до цього EC2 з VSC така сама, як і минулий раз, однак тепер не потрібно створювати файл config, а можна просто додати нові конфігурації у вже існуючий і після вибору Remote-SSH: Connect to Host у VSC обрати порт того інстансу, до якого хочете підключитися:

В принципі, алгоритм розгортання боту на цьому EC2 такий самий, як і минулого разу, однак, очевидно, змінилася адреса, звідки я клонувала репозиторій

git clone https://github.com/yahrdev/ EnGram_bot.git

а також – налаштування у файлі .env:

Як бачите, там вказано і адресу ElastiCache – це той інстанс, який ми зараз створимо. Що стосується адрес API, то тут все логічно: вказана приватна IPv4 адреса EC2, на якому лежить API.

Щоб вся ця система працювала і бот міг адекватно співпрацювати з API , забираючи звідти інформацію, нам доведеться створити Peering connection між двома VPC. Насправді варіантів «сконектити» мережі є досить багато, проте я, звичайно ж, обрала безкоштовний.

Які кроки необхідно зробити для налаштування такого конекшену:

1) У розділі Peering connections (VPC) створити новий конекшен:

2) Зайти в Route tables і для кожного роута (нагадаю, у нас їх два: для API  і для бота) додати інформацію про протилежний VPC, у графі Target обравши новостворений Peering connection. Тобто, наприклад, для Route table бота це виглядатиме наступним чином:

де 172.31.0.0/16 – це CIDR підмережі API (знайти його можна в полі IPv4 CIDR на відповідній підмережі). Те саме я робила і для Route table API, вказавши там CIDR підмережі бота.

І, до речі, після створення Peering connection варто не забути натиснути кнопку Accept Request на ньому (знаходиться у розділі Actions).

На жаль, це ще не все. Довелося також додати Security Group на інстанс нашого API, де вказати секюріті групу інстансу бота:

Для перевірки налаштувань можна внести наступну команду  у терміналі VSC, підключеного до інстансу бота:

curl -I http://port:8001, де port - Private IPv4 address інстансу EC2 API. 

Далі необхідно створити нове ElastiCache у новому VPC. Кроки створення точно такі самі, як і при створенні попереднього інстансу кешу. Варто також не забути додати Inbound Rule для security group новоствореного ElastiCache, де вказати security group EC2 бота.

Після перевірки конекшену EC2 бота з ElastiCache по аналогії, як було описано вище, я також коригувала код свого боту, оскільки і тут довелося замінювати aioredis на redis.asyncio.

Ну і, врешті-решт, останнім кроком у цьому процесі стала автоматизація, тобто додавання запуску боту на запуск EC2 бота. Код, який цього разу я вставила у файл Engproject.service, виглядав таким чином:

[Unit]
Description=EngApp
After=network.target

[Service]
User=ec2-user
WorkingDirectory=/home/ec2-user/EnGram_bot
ExecStart=/home/ec2-user/EnGram_bot/Envenv/bin/python3 /home/ec2-user/EnGram_bot/bot/main.py
Restart=always
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Тут необхідно буде знову запустити всі ті команди, які були описані раніше, щоб зберегти файл і поставити бот на автозапуск.

Після цього довгого і часом непростого шляху я нарешті запустила свій проект. Результат виглядав наступним чином:

Впевнена, цей шлях можна було пройти інакше, або навіть ускладнити, наприклад, додавши в цю архітектуру Load Balancer для великих навантажень. Але думаю, що не всім девелоперам зараз потрібне заглиблення у такі деталі. Тим більш перевірити роботу подібних балансерів на моєму проекті буде майже нереально.

Сподіваюся, дана стаття стала в нагоді і допомогла зробити крок назустріч AWS для тих, хто цього зараз конче потребував.