feat: Added final project
This commit is contained in:
1 parent
0302da1fd7
commit
b76898970b
12 files changed
+1118
No files matched your search
@@ -144,4 +144,15 @@ VKC_CASE_03_migration_РемизовКЛ_20260619.md,CASE,M08,CASE_03,Анали
|
|||||||
VKC_CASE_03_migration_IvanovII_20260619.drawio.png,DIAGRAM,M08,CASE_03,Схема целевой архитектуры интернет-магазина в VK Cloud,04_diagrams/VKC_CASE_03_migration_IvanovII_20260619.drawio.png,,final,
|
VKC_CASE_03_migration_IvanovII_20260619.drawio.png,DIAGRAM,M08,CASE_03,Схема целевой архитектуры интернет-магазина в VK Cloud,04_diagrams/VKC_CASE_03_migration_IvanovII_20260619.drawio.png,,final,
|
||||||
VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,CASE,M08,8.2,Проектирование высоконагруженной архитектуры интернет-магазина,01_reports/VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,,final,
|
VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,CASE,M08,8.2,Проектирование высоконагруженной архитектуры интернет-магазина,01_reports/VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,,final,
|
||||||
VKC_ARCH_M08_highload_store_diogram_РемизовКЛ_20260619.drawio.png,DIAGRAM,M08,8.2,Схема архитектуры высоконагруженного интернет-магазина,04_diagrams/VKC_ARCH_M08_highload_store_diogram_РемизовКЛ_20260619.drawio.png,VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,final,
|
VKC_ARCH_M08_highload_store_diogram_РемизовКЛ_20260619.drawio.png,DIAGRAM,M08,8.2,Схема архитектуры высоконагруженного интернет-магазина,04_diagrams/VKC_ARCH_M08_highload_store_diogram_РемизовКЛ_20260619.drawio.png,VKC_ARCH_M08_highload_store_REPORT_РемизовКЛ_20260619.md,final,
|
||||||
|
VKC_PROJ_V01_README_РемизовКЛ_20260628.md,PROJ,PROJ,V01,README итогового проекта,01_reports/VKC_PROJ_V01_README_РемизовКЛ_20260628.md,,final,
|
||||||
|
VKC_PROJ_V01_demo_video_РемизовКЛ_20260628.mp4,EVIDENCE,PROJ,V01,Видеообзор демонстрации,05_exports/VKC_PROJ_V01_demo_video_РемизовКЛ_20260628.mp4,final
|
||||||
|
VKC_PROJ_V01_presentation_РемизовКЛ_20260628.pdf,PRESENTATION,PROJ,V01,Презентация итогового проекта,05_exports/VKC_PROJ_V01_presentation_РемизовКЛ_20260628.pdf,final
|
||||||
|
VKC_PROJ_V01_architecture_РемизовКЛ_20260628.drawio.png,DIAGRAM,PROJ,V01,Архитектурная схема,04_diagrams/VKC_PROJ_V01_architecture_РемизовКЛ_20260628.drawio.png,final
|
||||||
|
VKC_PROJ_V01_ab_log_РемизовКЛ_20260628.log,EVIDENCE,PROJ,V01,Лог нагрузочного тестирования ab,02_evidence/VKC_PROJ_V01_ab_log_RemizovKL_20260628.log,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_curl_log_РемизовКЛ_20260628.log,EVIDENCE,PROJ,V01,Лог curl -v к /DevOps,02_evidence/VKC_PROJ_V01_curl_log_RemizovKL_20260628.log,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_ssh_log_РемизовКЛ_20260628.log,EVIDENCE,PROJ,V01,Лог SSH-подключений,02_evidence/VKC_PROJ_V01_ssh_log_RemizovKL_20260628.log,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_main_РемизовКЛ_20260628.tf,CODE,PROJ,V01,Основной код Terraform,03_code/VKC_PROJ_V01_main_РемизовКЛ_20260628.tf,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_variables_РемизовКЛ_20260628.tf,CODE,PROJ,V01,Переменные Terraform,03_code/VKC_PROJ_V01_variables_РемизовКЛ_20260628.tf,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_outputs_РемизовКЛ_20260628.tf,CODE,PROJ,V01,Выходные переменные Terraform,03_code/VKC_PROJ_V01_outputs_РемизовКЛ_20260628.tf,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
|
VKC_PROJ_V01_backend_РемизовКЛ_20260628.tf,CODE,PROJ,V01,Настройка бэкенда S3,03_code/VKC_PROJ_V01_backend_РемизовКЛ_20260628.tf,VKC_PROJ_V01_README_РемизовКЛ_20260628.md,final,
|
||||||
00_manifest.csv,MANIFEST,all,all,Финальный манифест сдачи,00_manifest.csv,,final,
|
00_manifest.csv,MANIFEST,all,all,Финальный манифест сдачи,00_manifest.csv,,final,
|
||||||
|
@@ -0,0 +1,191 @@
|
|||||||
|
---
|
||||||
|
course_code: VKCLOUD-80
|
||||||
|
artifact_type: PROJ
|
||||||
|
project_variant: 1
|
||||||
|
project_title: Отказоустойчивый веб-хостинг на Docker + Terraform (VK Cloud)
|
||||||
|
student_fio: Ремизов Кирилл Львович
|
||||||
|
date: 2026-06-28
|
||||||
|
source_docs:
|
||||||
|
- Д1
|
||||||
|
- Д9
|
||||||
|
attached_files:
|
||||||
|
- VKC_PROJ_V01_demo_video_RemizovKL_20260628.mp4
|
||||||
|
- VKC_PROJ_V01_ab_log_RemizovKL_20260628.log
|
||||||
|
- VKC_PROJ_V01_curl_log_RemizovKL_20260628.log
|
||||||
|
- VKC_PROJ_V01_ssh_log_RemizovKL_20260628.log
|
||||||
|
- VKC_PROJ_V01_terraform_state_list_RemizovKL_20260628.txt
|
||||||
|
- VKC_PROJ_V01_architecture.drawio.png
|
||||||
|
- VKC_PROJ_V01_backend_РемизовКЛ_20260628.tf
|
||||||
|
- VKC_PROJ_V01_main_РемизовКЛ_20260628.tf
|
||||||
|
- VKC_PROJ_V01_outputs_РемизовКЛ_20260628.tf
|
||||||
|
- VKC_PROJ_V01_variables_РемизовКЛ_20260628.tf
|
||||||
|
repo_url:
|
||||||
|
- https://github.com/BlackCorbeau/final_assessment
|
||||||
|
- https://git.rustprogersteam.ru/Black_Raven/MyResume
|
||||||
|
demo_url: http://95.163.213.173/DevOps
|
||||||
|
status: final
|
||||||
|
---
|
||||||
|
|
||||||
|
# README итогового проекта
|
||||||
|
|
||||||
|
## 1. Цель проекта
|
||||||
|
|
||||||
|
Развернуть отказоустойчивую инфраструктуру для веб‑приложения (сайт‑резюме), упакованного в Docker‑образ, с использованием виртуальных машин, балансировщика нагрузки и управляемой базы данных (PostgreSQL) в облаке VK Cloud. Вся инфраструктура описывается кодом (Terraform), управляется через GitHub Actions и обеспечивает доступность сайта при отказе одного из веб‑серверов (SLA 99.9%).
|
||||||
|
|
||||||
|
## 2. Выбранный вариант и почему он выбран
|
||||||
|
|
||||||
|
**Выбран вариант №1 из Документа 9** – *«Отказоустойчивый веб‑хостинг на ВМ»*, но с заменой ручного Nginx на Docker‑контейнер с собственным приложением.
|
||||||
|
|
||||||
|
**Почему выбран:**
|
||||||
|
- Этот вариант покрывает все ключевые темы курса: сеть, безопасность, балансировка, работа с базами данных, автоматизация.
|
||||||
|
- Он позволяет продемонстрировать навыки работы с Terraform, Docker, CI/CD и облачными сервисами VK Cloud.
|
||||||
|
- Стек соответствует реальным задачам промышленной эксплуатации.
|
||||||
|
- Проект имеет чёткие критерии успеха и позволяет наглядно показать отказоустойчивость.
|
||||||
|
|
||||||
|
## 3. Архитектура
|
||||||
|
|
||||||
|
### Схема
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
*Схема создана в draw.io и отражает все компоненты инфраструктуры.*
|
||||||
|
|
||||||
|
### Основные компоненты
|
||||||
|
|
||||||
|
- **Виртуальные машины**:
|
||||||
|
- **2 веб‑сервера** (flavor `Basic-1-1-10`) в приватной подсети – на каждом запущен Docker‑контейнер с приложением (образ из приватного реестра).
|
||||||
|
- **Бастион** (flavor `Basic-1-1-10`) в публичной подсети – единственная точка входа по SSH для управления.
|
||||||
|
- **Балансировщик нагрузки** (Application L7) с публичным Floating IP – распределяет HTTP‑трафик между веб‑серверами, выполняет health‑check по пути `/DevOps`.
|
||||||
|
- **Управляемая PostgreSQL** (flavor `Standard-2-8-50`) – создана в приватной подсети, но приложение к ней не подключается (архитектурный задел для будущей интеграции).
|
||||||
|
|
||||||
|
### Сетевой контур
|
||||||
|
|
||||||
|
- **VPC** с двумя подсетями:
|
||||||
|
- **public** (192.168.1.0/24) – для балансировщика и бастиона.
|
||||||
|
- **private** (192.168.2.0/24) – для веб‑серверов и БД.
|
||||||
|
- Интернет‑шлюз подключён к роутеру, обеспечивает доступ к публичным IP.
|
||||||
|
- Бастион имеет Floating IP, доступ по SSH разрешён только с моего IP-адреса.
|
||||||
|
|
||||||
|
### Безопасность
|
||||||
|
|
||||||
|
- **Security Groups**:
|
||||||
|
- `main` – разрешает HTTP (80) для всех, SSH (22) только с моего IP, исходящий трафик разрешён.
|
||||||
|
- `db_sg` – разрешает доступ к PostgreSQL (5432) только из приватной подсети.
|
||||||
|
- SSH‑доступ к веб‑серверам возможен только через бастион (используется проброс агента или скопированный ключ).
|
||||||
|
- Пароль к БД задан в коде (захардкожен для упрощения, в продакшене следует использовать переменные окружения или Vault).
|
||||||
|
|
||||||
|
### Мониторинг
|
||||||
|
|
||||||
|
- Health‑check балансировщика по HTTP `/DevOps` – проверяет доступность приложения.
|
||||||
|
- Нагрузочное тестирование с `ab` подтверждает стабильность (99.9% успешных запросов).
|
||||||
|
|
||||||
|
### Управление затратами
|
||||||
|
|
||||||
|
- Использованы минимальные флейворы `Basic-1-1-10` для ВМ и `Standard-2-8-50` для БД.
|
||||||
|
- Все ресурсы управляются Terraform, после защиты будут удалены командой `terraform destroy`.
|
||||||
|
- State хранится в S3, что исключает потерю состояния и лишние расходы.
|
||||||
|
|
||||||
|
## 4. Используемый стек
|
||||||
|
|
||||||
|
| Компонент | Технология |
|
||||||
|
|--------------------|------------------------------------------|
|
||||||
|
| Инфраструктура | Terraform (provider vkcs) |
|
||||||
|
| Оркестрация | Docker (контейнеры на ВМ) |
|
||||||
|
| Балансировка | VK Cloud Load Balancer (Application L7) |
|
||||||
|
| База данных | VK Cloud DBaaS (PostgreSQL 14) |
|
||||||
|
| CI/CD | GitHub Actions |
|
||||||
|
| Хранение состояния | S3 (VK Cloud Object Storage) |
|
||||||
|
| Язык приложения | Python (Flask) + Gunicorn |
|
||||||
|
| Контейнеризация | Docker, образ из приватного реестра |
|
||||||
|
|
||||||
|
## 5. Репозитории проекта
|
||||||
|
|
||||||
|
Исходный код проекта размещён в двух репозиториях:
|
||||||
|
|
||||||
|
- **GitHub (основной)** – [https://github.com/BlackCorbeau/final_assessment](https://github.com/BlackCorbeau/final_assessment)
|
||||||
|
- **Forgejo (зеркало)** – [https://git.rustprogersteam.ru/Black_Raven/MyResume](https://git.rustprogersteam.ru/Black_Raven/MyResume)
|
||||||
|
|
||||||
|
## 6. Порядок развертывания
|
||||||
|
|
||||||
|
1. **Подготовка окружения:**
|
||||||
|
- Убедиться, что установлены Terraform, OpenStack CLI, Docker (локально).
|
||||||
|
- Получить RC‑файл для доступа к VK Cloud, экспортировать переменные окружения или задать их в `terraform.tfvars`.
|
||||||
|
- Создать S3‑бакет для хранения state (имя `tf-state-final-assessment`).
|
||||||
|
|
||||||
|
2. **Клонирование репозитория:**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/BlackCorbeau/final_assessment.git
|
||||||
|
cd final_assessment/terraform
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Настройка переменных:**
|
||||||
|
- Скопировать `terraform.tfvars.example` в `terraform.tfvars` и заполнить все обязательные переменные:
|
||||||
|
```hcl
|
||||||
|
my_ip = "ваш_публичный_IP/32"
|
||||||
|
project_name = "final_assessment"
|
||||||
|
docker_image = "git.rustprogersteam.ru/black_raven/myresume/resume:latest"
|
||||||
|
vkcs_username = "..."
|
||||||
|
vkcs_password = "..."
|
||||||
|
vkcs_project_id = "..."
|
||||||
|
vkcs_region = "RegionOne"
|
||||||
|
vkcs_auth_url = "https://infra.mail.ru:35357/v3/"
|
||||||
|
ssh_public_key = "~/.ssh/id_rsa.pub"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Инициализация и применение:**
|
||||||
|
```bash
|
||||||
|
terraform init
|
||||||
|
terraform plan
|
||||||
|
terraform apply -auto-approve
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Автоматический деплой через GitHub Actions:**
|
||||||
|
- При пуше в ветку `main` workflow выполняет `terraform plan` и `apply` автоматически (требуются секреты: `VKCS_USERNAME`, `VKCS_PASSWORD`, `VKCS_PROJECT_ID`, `VKCS_AUTH_URL`, `MY_IP`, `SSH_PUBLIC_KEY` и др.).
|
||||||
|
|
||||||
|
6. **Проверка outputs:**
|
||||||
|
- После успешного apply получаем:
|
||||||
|
- `load_balancer_ip` – публичный IP балансировщика.
|
||||||
|
- `bastion_floating_ip` – IP бастиона.
|
||||||
|
- `db_host`, `db_name`, `db_user`, `db_password` – параметры БД.
|
||||||
|
|
||||||
|
## 7. Проверка работоспособности
|
||||||
|
|
||||||
|
Все этапы проверки зафиксированы в видеообзоре `VKC_PROJ_V01_demo_video_RemizovKL_20260628.mp4`:
|
||||||
|
|
||||||
|
| Этап | Действие | Метка времени в видео |
|
||||||
|
| ---- | ---------------------------------------------------------------------------------------------- | --------------------- |
|
||||||
|
| 1 | Просмотр созданных ресурсов в консоли VK Cloud (ВМ, балансировщик, БД) | 00:00 – 01:13 |
|
||||||
|
| 2 | Проверка доступности сайта через браузер (http://95.163.213.173/DevOps) | 01:14 – 01:26 |
|
||||||
|
| 3 | Подключение к бастиону и веб‑серверам через SSH, проверка запущенных контейнеров (`docker ps`) | 01:27 – 01:50 |
|
||||||
|
| 4 | Остановка контейнера на web-1 (`docker stop`), проверка, что сайт продолжает работать | 01:51 – 03:09 |
|
||||||
|
| 5 | Запуск контейнера обратно (`docker start`), возвращение в пул | 03:10 – 04:15 |
|
||||||
|
| 6 | Подключение к PostgreSQL через `psql` (подтверждение наличия БД) | 04:16 – 05:32 |
|
||||||
|
| 7 | Нагрузочное тестирование `ab -n 1000 -c 10` с выводом результатов | 05:33 – 05:53 |
|
||||||
|
|
||||||
|
Также приложены отдельные логи:
|
||||||
|
- `VKC_PROJ_V01_ab_log_RemizovKL_20260628.log` – полный вывод нагрузочного теста.
|
||||||
|
- `VKC_PROJ_V01_curl_log_RemizovKL_20260628.log` – вывод `curl -v`.
|
||||||
|
- `VKC_PROJ_V01_ssh_log_RemizovKL_20260628.log` – лог SSH-сессий.
|
||||||
|
|
||||||
|
## 8. Известные ограничения
|
||||||
|
|
||||||
|
- Пароль БД захардкожен в коде – в продакшене использовать переменные.
|
||||||
|
- Health‑check использует `/DevOps` (не выделенный `/health`).
|
||||||
|
- Образ собран с тегом `latest` – обновление требует ручного изменения тега.
|
||||||
|
- Отсутствует мониторинг (Prometheus/Grafana) – проект сфокусирован на базовой отказоустойчивости.
|
||||||
|
|
||||||
|
## 9. Приложенные файлы
|
||||||
|
|
||||||
|
| Файл | Назначение |
|
||||||
|
|------|------------|
|
||||||
|
| `VKC_PROJ_V01_README_RemizovKL_20260628.md` | Данный файл – полный отчёт по проекту. |
|
||||||
|
| `VKC_PROJ_V01_demo_video_RemizovKL_20260628.mp4` | **Видеообзор** со всеми этапами проверки (сайт, SSH, отказоустойчивость, нагрузка, БД, консоль). |
|
||||||
|
| `VKC_PROJ_V01_ab_log_RemizovKL_20260628.log` | Лог нагрузочного тестирования `ab`. |
|
||||||
|
| `VKC_PROJ_V01_curl_log_RemizovKL_20260628.log` | Лог `curl -v` к `/DevOps`. |
|
||||||
|
| `VKC_PROJ_V01_ssh_log_RemizovKL_20260628.log` | Лог SSH-подключений и проверки контейнеров. |
|
||||||
|
| `VKC_PROJ_V01_terraform_state_list_RemizovKL_20260628.txt` | Вывод `terraform state list`. |
|
||||||
|
| `VKC_PROJ_V01_architecture.drawio.png` | Архитектурная схема. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Итог:** Проект полностью соответствует требованиям варианта №1, все критерии успеха выполнены, инфраструктура работоспособна и готова к защите. Видеообзор содержит все необходимые доказательства.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
~/rosatom/final_asessment_terraform
|
||||||
|
nix-shell ❯ ab -n 1000 -c 10 http://95.163.213.173/DevOps via 💠 default on ☁️ (ru-msk)
|
||||||
|
This is ApacheBench, Version 2.3 <$Revision: 1923142 $>
|
||||||
|
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||||
|
Licensed to The Apache Software Foundation, http://www.apache.org/
|
||||||
|
|
||||||
|
Benchmarking 95.163.213.173 (be patient)
|
||||||
|
Completed 100 requests
|
||||||
|
Completed 200 requests
|
||||||
|
Completed 300 requests
|
||||||
|
Completed 400 requests
|
||||||
|
Completed 500 requests
|
||||||
|
Completed 600 requests
|
||||||
|
Completed 700 requests
|
||||||
|
Completed 800 requests
|
||||||
|
Completed 900 requests
|
||||||
|
Completed 1000 requests
|
||||||
|
Finished 1000 requests
|
||||||
|
|
||||||
|
|
||||||
|
Server Software: gunicorn
|
||||||
|
Server Hostname: 95.163.213.173
|
||||||
|
Server Port: 80
|
||||||
|
|
||||||
|
Document Path: /DevOps
|
||||||
|
Document Length: 10796 bytes
|
||||||
|
|
||||||
|
Concurrency Level: 10
|
||||||
|
Time taken for tests: 13.065 seconds
|
||||||
|
Complete requests: 1000
|
||||||
|
Failed requests: 1
|
||||||
|
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
|
||||||
|
Total transferred: 10922067 bytes
|
||||||
|
HTML transferred: 10785204 bytes
|
||||||
|
Requests per second: 76.54 [#/sec] (mean)
|
||||||
|
Time per request: 130.653 [ms] (mean)
|
||||||
|
Time per request: 13.065 [ms] (mean, across all concurrent requests)
|
||||||
|
Transfer rate: 816.36 [Kbytes/sec] received
|
||||||
|
|
||||||
|
Connection Times (ms)
|
||||||
|
min mean[+/-sd] median max
|
||||||
|
Connect: 0 0 0.1 0 1
|
||||||
|
Processing: 25 114 334.8 62 5001
|
||||||
|
Waiting: 0 105 296.8 57 4156
|
||||||
|
Total: 25 114 334.8 62 5001
|
||||||
|
|
||||||
|
Percentage of the requests served within a certain time (ms)
|
||||||
|
50% 62
|
||||||
|
66% 73
|
||||||
|
75% 79
|
||||||
|
80% 83
|
||||||
|
90% 95
|
||||||
|
95% 113
|
||||||
|
98% 1114
|
||||||
|
99% 2100
|
||||||
|
100% 5001 (longest request)
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
~/r/final_assessment/terraform on main [?ok]
|
||||||
|
nix-shell ❯ curl -v http://95.163.213.173/DevOps via 💠 default on ☁️ (ru-msk)
|
||||||
|
* Trying 95.163.213.173:80...
|
||||||
|
* Established connection to 95.163.213.173 (95.163.213.173 port 80) from 198.18.0.1 port 57226
|
||||||
|
* using HTTP/1.x
|
||||||
|
> GET /DevOps HTTP/1.1
|
||||||
|
> Host: 95.163.213.173
|
||||||
|
> User-Agent: curl/8.20.0
|
||||||
|
> Accept: */*
|
||||||
|
>
|
||||||
|
* Request completely sent off
|
||||||
|
< HTTP/1.1 200 OK
|
||||||
|
< server: gunicorn
|
||||||
|
< date: Sun, 28 Jun 2026 10:29:17 GMT
|
||||||
|
< content-type: text/html; charset=utf-8
|
||||||
|
< content-length: 10796
|
||||||
|
<
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Кирилл Ремизов</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap">
|
||||||
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Шапка с фото и контактами -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="photo-section">
|
||||||
|
<div class="photo-slider" id="photoSlider">
|
||||||
|
<!-- Фотографии будут добавлены через JavaScript -->
|
||||||
|
</div>
|
||||||
|
<div class="slider-controls" id="sliderControls">
|
||||||
|
<!-- Точки управления слайдером будут добавлены через JavaScript -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-section">
|
||||||
|
<h1>Ремизов Кирилл Львович</h1>
|
||||||
|
<div class="subtitle">Интересующее направление: SRE/DevOps инженер</div>
|
||||||
|
|
||||||
|
<p>Студент 3 курса ННГУ им. Лобачевского по направлению "Программная инженерия" (Средний бал: 3,85). Стремлюсь к профессиональному росту: изучаю новые технологии, алгоритмы и подходы к разработке. Как молодой специалист, подхожу к работе с энтузиазмом и готов вкладываться в сложные проекты.</p>
|
||||||
|
|
||||||
|
<div class="contacts">
|
||||||
|
<div class="contact-item">
|
||||||
|
<div class="contact-icon">
|
||||||
|
<i class="fas fa-phone"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><a href="tel:+79051932953">+7 (905) 193-29-53</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-item">
|
||||||
|
<div class="contact-icon">
|
||||||
|
<i class="fas fa-envelope"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><a href="mailto:remizov.kirill2005@yandex.ru">remizov.kirill2005@yandex.ru</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-item">
|
||||||
|
<div class="contact-icon">
|
||||||
|
<i class="fab fa-telegram"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><a href="https://t.me/simpleRussianProger" target="_blank">@simpleRussianProger</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-item">
|
||||||
|
<div class="contact-icon">
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><a href="https://github.com/BlackCorbeau" target="_blank">BlackCorbeau (GitHub)</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contact-item">
|
||||||
|
<div class="contact-icon">
|
||||||
|
<i class="fab fa-git-alt"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div><a href="https://git.rustprogersteam.ru/Black_Raven" target="_blank">RemizovKL (Forgejo)</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<!-- Левая колонка -->
|
||||||
|
<div class="left-column">
|
||||||
|
<!-- Образование -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-graduation-cap"></i>
|
||||||
|
<span>Образование</span>
|
||||||
|
</div>
|
||||||
|
<p><strong>2023–2027 ННГУ им. Лобачевского</strong>, Нижний Новгород</p>
|
||||||
|
<p style="color: var(--text-muted); margin-top: 5px;">Программная инженерия</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Достижения -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-trophy"></i>
|
||||||
|
<span>Достижения</span>
|
||||||
|
</div>
|
||||||
|
<p><strong>2025</strong> Участие в хакатоне от IT-холдинга Т1, 3-е место.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Языки -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-globe"></i>
|
||||||
|
<span>Языки</span>
|
||||||
|
</div>
|
||||||
|
<ul class="list">
|
||||||
|
<li>Английский (B2)</li>
|
||||||
|
<li>Французский (разговорный)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Soft Skills -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-users"></i>
|
||||||
|
<span>Soft Skills</span>
|
||||||
|
</div>
|
||||||
|
<ul class="list">
|
||||||
|
<li>Ответственный и пунктуальный</li>
|
||||||
|
<li>Любовь к своему делу</li>
|
||||||
|
<li>Умение работать в команде</li>
|
||||||
|
<li>Открыт к обмену опытом</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Правая колонка -->
|
||||||
|
<div class="right-column">
|
||||||
|
<!-- Технические навыки -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-cogs"></i>
|
||||||
|
<span>Технические навыки</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>C++</span>
|
||||||
|
<span>5/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 100%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>Rust</span>
|
||||||
|
<span>4/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 80%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>SQL</span>
|
||||||
|
<span>3/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 60%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>Python</span>
|
||||||
|
<span>2/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 40%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>CI/CD</span>
|
||||||
|
<span>5/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 100%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>Linux</span>
|
||||||
|
<span>5/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 100%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="skill-item">
|
||||||
|
<div class="skill-header">
|
||||||
|
<span>Docker</span>
|
||||||
|
<span>5/5</span>
|
||||||
|
</div>
|
||||||
|
<div class="skill-bar">
|
||||||
|
<div class="skill-level" style="width: 100%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Профессиональные навыки -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-tools"></i>
|
||||||
|
<span>Профессиональные навыки</span>
|
||||||
|
</div>
|
||||||
|
<div class="two-column-list">
|
||||||
|
<ul class="list">
|
||||||
|
<li>Работа с терминалом</li>
|
||||||
|
<li>Vim</li>
|
||||||
|
<li>Docker</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="list">
|
||||||
|
<li>Kubernetes</li>
|
||||||
|
<li>*nix системы</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Ссылка на репозиторий -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">
|
||||||
|
<i class="fas fa-code-branch"></i>
|
||||||
|
<span>Репозиторий проекта</span>
|
||||||
|
</div>
|
||||||
|
<p>Исходный код этого резюме доступны в репозитории:</p>
|
||||||
|
<a href="https://git.rustprogersteam.ru/Black_Raven/MyResume" target="_blank" class="repo-link">
|
||||||
|
<i class="fab fa-git-alt"></i>
|
||||||
|
<span>https://git.rustprogersteam.ru/Black_Raven/MyResume</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p><i class="fas fa-heart" style="color: var(--primary);"></i> Обновлено: <span id="currentDate"></span></p>
|
||||||
|
<p style="margin-top: 10px; font-size: 0.8rem;">Стиль вдохновлен Forgejo | Черно-оранжевая цветовая схема</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/script.js"></script>
|
||||||
|
</body>
|
||||||
|
* Connection #0 to host 95.163.213.173:80 left intact
|
||||||
|
</html>%
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
~/r/final_assessment/terraform on main [ok]
|
||||||
|
nix-shell ❯ scp -i ~/.ssh/id_rsa ~/.ssh/id_rsa ubuntu@95.163.215.1:/home/ubuntu/.ssh/id_rsa via 💠 default on ☁️ (ru-msk)
|
||||||
|
The authenticity of host '95.163.215.1 (95.163.215.1)' can't be established.
|
||||||
|
ED25519 key fingerprint is: SHA256:IhiPDFfSS5rEQ83Sws/pkRp91/BsVD+kiZJwhG6G/H8
|
||||||
|
This key is not known by any other names.
|
||||||
|
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
|
||||||
|
Warning: Permanently added '95.163.215.1' (ED25519) to the list of known hosts.
|
||||||
|
** WARNING: connection is not using a post-quantum key exchange algorithm.
|
||||||
|
** This session may be vulnerable to "store now, decrypt later" attacks.
|
||||||
|
** The server may need to be upgraded. See https://openssh.com/pq.html
|
||||||
|
id_rsa 100% 2602 192.9KB/s 00:00
|
||||||
|
|
||||||
|
~/r/final_assessment/terraform on main [ok]
|
||||||
|
nix-shell ❯ ssh -A -i ~/.ssh/id_rsa ubuntu@95.163.215.1 via 💠 default on ☁️ (ru-msk)
|
||||||
|
** WARNING: connection is not using a post-quantum key exchange algorithm.
|
||||||
|
** This session may be vulnerable to "store now, decrypt later" attacks.
|
||||||
|
** The server may need to be upgraded. See https://openssh.com/pq.html
|
||||||
|
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)
|
||||||
|
|
||||||
|
* Documentation: https://help.ubuntu.com
|
||||||
|
* Management: https://landscape.canonical.com
|
||||||
|
* Support: https://ubuntu.com/pro
|
||||||
|
|
||||||
|
System information as of Sun Jun 28 10:23:32 UTC 2026
|
||||||
|
|
||||||
|
System load: 0.0 Processes: 101
|
||||||
|
Usage of /: 9.0% of 19.20GB Users logged in: 0
|
||||||
|
Memory usage: 20% IPv4 address for ens3: 192.168.1.10
|
||||||
|
Swap usage: 0%
|
||||||
|
|
||||||
|
|
||||||
|
Expanded Security Maintenance for Infrastructure is not enabled.
|
||||||
|
|
||||||
|
0 updates can be applied immediately.
|
||||||
|
|
||||||
|
128 additional security updates can be applied with ESM Infra.
|
||||||
|
Learn more about enabling ESM Infra service for Ubuntu 20.04 at
|
||||||
|
https://ubuntu.com/20-04
|
||||||
|
|
||||||
|
New release '22.04.5 LTS' available.
|
||||||
|
Run 'do-release-upgrade' to upgrade to it.
|
||||||
|
|
||||||
|
|
||||||
|
Last login: Sun Jun 28 10:11:57 2026 from 95.26.148.233
|
||||||
|
ubuntu@final-assessment-bastion:~$ ssh ubuntu@192.168.2.10 # теперь должно работать
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
||||||
|
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
|
||||||
|
It is also possible that a host key has just been changed.
|
||||||
|
The fingerprint for the ECDSA key sent by the remote host is
|
||||||
|
SHA256:zXGSX2Tz1E2gWu5hYFEpl0465z0zTQAR4+3hjRQOQnc.
|
||||||
|
Please contact your system administrator.
|
||||||
|
Add correct host key in /home/ubuntu/.ssh/known_hosts to get rid of this message.
|
||||||
|
Offending ECDSA key in /home/ubuntu/.ssh/known_hosts:1
|
||||||
|
remove with:
|
||||||
|
ssh-keygen -f "/home/ubuntu/.ssh/known_hosts" -R "192.168.2.10"
|
||||||
|
ECDSA host key for 192.168.2.10 has changed and you have requested strict checking.
|
||||||
|
Host key verification failed.
|
||||||
|
ubuntu@final-assessment-bastion:~$ rm ~/.ssh/
|
||||||
|
authorized_keys id_rsa known_hosts
|
||||||
|
ubuntu@final-assessment-bastion:~$ rm ~/.ssh/
|
||||||
|
authorized_keys id_rsa known_hosts
|
||||||
|
ubuntu@final-assessment-bastion:~$ rm ~/.ssh/known_hosts
|
||||||
|
ubuntu@final-assessment-bastion:~$ ssh ubuntu@192.168.2.10 # теперь должно работать
|
||||||
|
The authenticity of host '192.168.2.10 (192.168.2.10)' can't be established.
|
||||||
|
ECDSA key fingerprint is SHA256:zXGSX2Tz1E2gWu5hYFEpl0465z0zTQAR4+3hjRQOQnc.
|
||||||
|
Are you sure you want to continue connecting (yes/no/[fingerprint])? ye
|
||||||
|
Please type 'yes', 'no' or the fingerprint: yes
|
||||||
|
Warning: Permanently added '192.168.2.10' (ECDSA) to the list of known hosts.
|
||||||
|
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)
|
||||||
|
|
||||||
|
* Documentation: https://help.ubuntu.com
|
||||||
|
* Management: https://landscape.canonical.com
|
||||||
|
* Support: https://ubuntu.com/pro
|
||||||
|
|
||||||
|
System information as of Sun Jun 28 10:24:27 UTC 2026
|
||||||
|
|
||||||
|
System load: 0.48 Processes: 115
|
||||||
|
Usage of /: 22.8% of 9.51GB Users logged in: 0
|
||||||
|
Memory usage: 33% IPv4 address for ens3: 192.168.2.10
|
||||||
|
Swap usage: 0%
|
||||||
|
|
||||||
|
|
||||||
|
Expanded Security Maintenance for Infrastructure is not enabled.
|
||||||
|
|
||||||
|
1 update can be applied immediately.
|
||||||
|
1 of these updates is a standard security update.
|
||||||
|
To see these additional updates run: apt list --upgradable
|
||||||
|
|
||||||
|
129 additional security updates can be applied with ESM Infra.
|
||||||
|
Learn more about enabling ESM Infra service for Ubuntu 20.04 at
|
||||||
|
https://ubuntu.com/20-04
|
||||||
|
|
||||||
|
|
||||||
|
ubuntu@final-assessment-web-1:~$ sudo docker ps
|
||||||
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||||
|
365edf425ac4 git.rustprogersteam.ru/black_raven/myresume/resume:latest "gunicorn app:app -b…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp upbeat_northcutt
|
||||||
|
ubuntu@final-assessment-web-1:~$ exit
|
||||||
|
logout
|
||||||
|
Connection to 192.168.2.10 closed.
|
||||||
|
ubuntu@final-assessment-bastion:~$ ssh ubuntu@192.168.2.11 # теперь должно работать
|
||||||
|
The authenticity of host '192.168.2.11 (192.168.2.11)' can't be established.
|
||||||
|
ECDSA key fingerprint is SHA256:NZ7FTKC5HtwQkpRs/4J4IPKzaQB5vEX0TRKZ5+t0hMI.
|
||||||
|
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
|
||||||
|
Warning: Permanently added '192.168.2.11' (ECDSA) to the list of known hosts.
|
||||||
|
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-216-generic x86_64)
|
||||||
|
|
||||||
|
* Documentation: https://help.ubuntu.com
|
||||||
|
* Management: https://landscape.canonical.com
|
||||||
|
* Support: https://ubuntu.com/pro
|
||||||
|
|
||||||
|
System information as of Sun Jun 28 10:25:13 UTC 2026
|
||||||
|
|
||||||
|
System load: 0.18 Processes: 117
|
||||||
|
Usage of /: 22.8% of 9.51GB Users logged in: 0
|
||||||
|
Memory usage: 31% IPv4 address for ens3: 192.168.2.11
|
||||||
|
Swap usage: 0%
|
||||||
|
|
||||||
|
|
||||||
|
Expanded Security Maintenance for Infrastructure is not enabled.
|
||||||
|
|
||||||
|
1 update can be applied immediately.
|
||||||
|
1 of these updates is a standard security update.
|
||||||
|
To see these additional updates run: apt list --upgradable
|
||||||
|
|
||||||
|
129 additional security updates can be applied with ESM Infra.
|
||||||
|
Learn more about enabling ESM Infra service for Ubuntu 20.04 at
|
||||||
|
https://ubuntu.com/20-04
|
||||||
|
|
||||||
|
|
||||||
|
ubuntu@final-assessment-web-2:~$ sudo docker ps
|
||||||
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||||
|
540a7f938ba0 git.rustprogersteam.ru/black_raven/myresume/resume:latest "gunicorn app:app -b…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp lucid_cerf
|
||||||
|
ubuntu@final-assessment-web-2:~$ exit
|
||||||
|
logout
|
||||||
|
Connection to 192.168.2.11 closed.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
terraform {
|
||||||
|
backend "s3" {
|
||||||
|
bucket = "tf-state-final-assessment" # имя твоего бакета (должен существовать)
|
||||||
|
key = "final-assessment/terraform.tfstate" # путь к файлу состояния внутри бакета
|
||||||
|
region = "ru-msk" # твой регион
|
||||||
|
endpoint = "https://hb.ru-msk.vkcloud-storage.ru"
|
||||||
|
skip_region_validation = true
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
vkcs = {
|
||||||
|
source = "vk-cs/vkcs"
|
||||||
|
version = "~> 0.1"
|
||||||
|
}
|
||||||
|
random = {
|
||||||
|
source = "hashicorp/random"
|
||||||
|
version = "~> 3.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "vkcs" {
|
||||||
|
username = var.vkcs_username
|
||||||
|
password = var.vkcs_password
|
||||||
|
project_id = var.vkcs_project_id
|
||||||
|
region = var.vkcs_region
|
||||||
|
auth_url = var.vkcs_auth_url
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_networking_network" "extnet" {
|
||||||
|
name = var.external_network_name
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_networking_secgroup" "ssh" {
|
||||||
|
name = "ssh"
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_networking_router" "router" {
|
||||||
|
id = var.router_id
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_images_image" "ubuntu" {
|
||||||
|
name = var.image_name
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_compute_flavor" "web" {
|
||||||
|
name = var.flavor_web
|
||||||
|
}
|
||||||
|
|
||||||
|
data "vkcs_compute_flavor" "bastion" {
|
||||||
|
name = var.flavor_bastion
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Сеть ---
|
||||||
|
resource "vkcs_networking_network" "main" {
|
||||||
|
name = "${var.project_name}-network"
|
||||||
|
sdn = "sprut"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_subnet" "public" {
|
||||||
|
name = "${var.project_name}-public-subnet"
|
||||||
|
network_id = vkcs_networking_network.main.id
|
||||||
|
cidr = var.public_subnet_cidr
|
||||||
|
dns_nameservers = ["8.8.8.8", "1.1.1.1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_subnet" "private" {
|
||||||
|
name = "${var.project_name}-private-subnet"
|
||||||
|
network_id = vkcs_networking_network.main.id
|
||||||
|
cidr = var.private_subnet_cidr
|
||||||
|
dns_nameservers = ["8.8.8.8", "1.1.1.1"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_router_interface" "public" {
|
||||||
|
router_id = data.vkcs_networking_router.router.id
|
||||||
|
subnet_id = vkcs_networking_subnet.public.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_router_interface" "private" {
|
||||||
|
router_id = data.vkcs_networking_router.router.id
|
||||||
|
subnet_id = vkcs_networking_subnet.private.id
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Security Groups ---
|
||||||
|
resource "vkcs_networking_secgroup" "main" {
|
||||||
|
name = "${var.project_name}-secgroup"
|
||||||
|
description = "Security group for VMs"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_secgroup_rule" "ssh" {
|
||||||
|
security_group_id = vkcs_networking_secgroup.main.id
|
||||||
|
direction = "ingress"
|
||||||
|
protocol = "tcp"
|
||||||
|
port_range_min = 22
|
||||||
|
port_range_max = 22
|
||||||
|
remote_ip_prefix = "${var.my_ip}/32"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_secgroup_rule" "http" {
|
||||||
|
security_group_id = vkcs_networking_secgroup.main.id
|
||||||
|
direction = "ingress"
|
||||||
|
protocol = "tcp"
|
||||||
|
port_range_min = 80
|
||||||
|
port_range_max = 80
|
||||||
|
remote_ip_prefix = "0.0.0.0/0"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_secgroup_rule" "egress" {
|
||||||
|
security_group_id = vkcs_networking_secgroup.main.id
|
||||||
|
direction = "egress"
|
||||||
|
remote_ip_prefix = "0.0.0.0/0"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security Group для базы данных
|
||||||
|
resource "vkcs_networking_secgroup" "db_sg" {
|
||||||
|
name = "${var.project_name}-db-sg"
|
||||||
|
description = "Security group for PostgreSQL"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_secgroup_rule" "db_ingress" {
|
||||||
|
security_group_id = vkcs_networking_secgroup.db_sg.id
|
||||||
|
direction = "ingress"
|
||||||
|
protocol = "tcp"
|
||||||
|
port_range_min = 5432
|
||||||
|
port_range_max = 5432
|
||||||
|
remote_ip_prefix = var.private_subnet_cidr
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Key Pair ---
|
||||||
|
resource "vkcs_compute_keypair" "my_key" {
|
||||||
|
name = "${var.project_name}-key"
|
||||||
|
public_key = file(var.ssh_public_key)
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Веб-серверы (Docker, без логина) ---
|
||||||
|
resource "vkcs_compute_instance" "web" {
|
||||||
|
count = 2
|
||||||
|
name = "${var.project_name}-web-${count.index + 1}"
|
||||||
|
flavor_id = data.vkcs_compute_flavor.web.id
|
||||||
|
key_pair = vkcs_compute_keypair.my_key.name
|
||||||
|
security_group_ids = [vkcs_networking_secgroup.main.id, data.vkcs_networking_secgroup.ssh.id]
|
||||||
|
availability_zone = "MS1"
|
||||||
|
|
||||||
|
block_device {
|
||||||
|
uuid = data.vkcs_images_image.ubuntu.id
|
||||||
|
source_type = "image"
|
||||||
|
destination_type = "volume"
|
||||||
|
volume_type = "ceph-ssd"
|
||||||
|
volume_size = var.volume_size_web
|
||||||
|
boot_index = 0
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
|
|
||||||
|
network {
|
||||||
|
uuid = vkcs_networking_network.main.id
|
||||||
|
fixed_ip_v4 = cidrhost(var.private_subnet_cidr, count.index + 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
# user_data – без логина, просто run
|
||||||
|
user_data = <<-EOF
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Установка Docker
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y docker.io
|
||||||
|
systemctl enable docker
|
||||||
|
systemctl start docker
|
||||||
|
|
||||||
|
# Ждём, пока Docker-демон полностью запустится
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Запускаем контейнер с повторными попытками, если образ не скачался
|
||||||
|
MAX_ATTEMPTS=5
|
||||||
|
ATTEMPT=0
|
||||||
|
until [ $ATTEMPT -ge $MAX_ATTEMPTS ]
|
||||||
|
do
|
||||||
|
echo "Attempt $((ATTEMPT+1)): pulling and running container..."
|
||||||
|
docker run -d --restart=always -p 80:80 ${var.docker_image} && break
|
||||||
|
ATTEMPT=$((ATTEMPT+1))
|
||||||
|
echo "Failed. Retrying in 10 seconds..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
|
||||||
|
# Если после всех попыток контейнер не запустился – пишем ошибку в лог
|
||||||
|
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
|
||||||
|
echo "ERROR: Failed to run container after $MAX_ATTEMPTS attempts." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Container started successfully."
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
web_private_ips = vkcs_compute_instance.web[*].network[0].fixed_ip_v4
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Балансировщик ---
|
||||||
|
resource "vkcs_lb_loadbalancer" "main" {
|
||||||
|
name = "${var.project_name}-lb"
|
||||||
|
vip_subnet_id = vkcs_networking_subnet.public.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_lb_listener" "http" {
|
||||||
|
name = "${var.project_name}-listener"
|
||||||
|
loadbalancer_id = vkcs_lb_loadbalancer.main.id
|
||||||
|
protocol = "HTTP"
|
||||||
|
protocol_port = 80
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_lb_pool" "web" {
|
||||||
|
name = "${var.project_name}-pool"
|
||||||
|
protocol = "HTTP"
|
||||||
|
lb_method = "ROUND_ROBIN"
|
||||||
|
listener_id = vkcs_lb_listener.http.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_lb_monitor" "web" {
|
||||||
|
pool_id = vkcs_lb_pool.web.id
|
||||||
|
type = "HTTP"
|
||||||
|
url_path = "/DevOps"
|
||||||
|
delay = 10
|
||||||
|
timeout = 5
|
||||||
|
max_retries = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_lb_member" "web" {
|
||||||
|
count = 2
|
||||||
|
pool_id = vkcs_lb_pool.web.id
|
||||||
|
address = local.web_private_ips[count.index]
|
||||||
|
protocol_port = 80
|
||||||
|
subnet_id = vkcs_networking_subnet.private.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_floatingip" "lb" {
|
||||||
|
pool = data.vkcs_networking_network.extnet.name
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_floatingip_associate" "lb" {
|
||||||
|
floating_ip = vkcs_networking_floatingip.lb.address
|
||||||
|
port_id = vkcs_lb_loadbalancer.main.vip_port_id
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Бастион (без мониторинга) ---
|
||||||
|
resource "vkcs_compute_instance" "bastion" {
|
||||||
|
name = "${var.project_name}-bastion"
|
||||||
|
flavor_id = data.vkcs_compute_flavor.bastion.id
|
||||||
|
key_pair = vkcs_compute_keypair.my_key.name
|
||||||
|
security_group_ids = [vkcs_networking_secgroup.main.id, data.vkcs_networking_secgroup.ssh.id]
|
||||||
|
availability_zone = "MS1"
|
||||||
|
|
||||||
|
block_device {
|
||||||
|
uuid = data.vkcs_images_image.ubuntu.id
|
||||||
|
source_type = "image"
|
||||||
|
destination_type = "volume"
|
||||||
|
volume_type = "ceph-ssd"
|
||||||
|
volume_size = var.volume_size_bastion
|
||||||
|
boot_index = 0
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
|
|
||||||
|
network {
|
||||||
|
uuid = vkcs_networking_network.main.id
|
||||||
|
fixed_ip_v4 = cidrhost(var.public_subnet_cidr, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
user_data = <<-EOF
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl wget htop
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_floatingip" "bastion" {
|
||||||
|
pool = data.vkcs_networking_network.extnet.name
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_networking_floatingip_associate" "bastion" {
|
||||||
|
floating_ip = vkcs_networking_floatingip.bastion.address
|
||||||
|
port_id = vkcs_compute_instance.bastion.network[0].port
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Управляемая PostgreSQL ---
|
||||||
|
resource "vkcs_db_instance" "postgres" {
|
||||||
|
name = "${var.project_name}-postgres"
|
||||||
|
flavor_id = "bf714720-78da-4271-ab7d-0cf5e2613f14" # Standard-2-8-50
|
||||||
|
size = 10
|
||||||
|
volume_type = "ceph-ssd"
|
||||||
|
network {
|
||||||
|
subnet_id = vkcs_networking_subnet.private.id
|
||||||
|
}
|
||||||
|
availability_zone = "MS1"
|
||||||
|
datastore {
|
||||||
|
type = "postgresql"
|
||||||
|
version = "14"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_db_database" "app_db" {
|
||||||
|
dbms_id = vkcs_db_instance.postgres.id
|
||||||
|
name = "app_db"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "vkcs_db_user" "app_user" {
|
||||||
|
dbms_id = vkcs_db_instance.postgres.id
|
||||||
|
name = "app_user"
|
||||||
|
password = "*#User23786590#*"
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
output "load_balancer_ip" {
|
||||||
|
value = vkcs_networking_floatingip.lb.address
|
||||||
|
description = "Публичный IP балансировщика"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "bastion_floating_ip" {
|
||||||
|
value = vkcs_networking_floatingip.bastion.address
|
||||||
|
description = "Публичный IP ВМ бастиона"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_private_ips" {
|
||||||
|
value = local.web_private_ips
|
||||||
|
description = "Приватные IP веб-серверов"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "ssh_to_bastion" {
|
||||||
|
value = "ssh -i ~/.ssh/id_rsa ubuntu@${vkcs_networking_floatingip.bastion.address}"
|
||||||
|
description = "Команда для подключения к бастиону"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "db_host" {
|
||||||
|
value = vkcs_db_instance.postgres.network[0].fixed_ip_v4
|
||||||
|
description = "Приватный IP инстанса PostgreSQL"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "db_name" {
|
||||||
|
value = vkcs_db_database.app_db.name
|
||||||
|
description = "Имя базы данных"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "db_user" {
|
||||||
|
value = vkcs_db_user.app_user.name
|
||||||
|
description = "Имя пользователя БД"
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
variable "my_ip" {
|
||||||
|
description = "Ваш публичный IP для SSH (узнать через curl ifconfig.me)"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "project_name" {
|
||||||
|
description = "Префикс для имен ресурсов"
|
||||||
|
type = string
|
||||||
|
default = "final_assessment"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "router_id" {
|
||||||
|
description = "ID существующего роутера"
|
||||||
|
type = string
|
||||||
|
default = "913bdd47-9155-45b2-b404-5c10d0086132"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "external_network_name" {
|
||||||
|
description = "Имя внешней сети для Floating IP"
|
||||||
|
type = string
|
||||||
|
default = "internet"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_public_key" {
|
||||||
|
description = "Путь к публичному SSH-ключу"
|
||||||
|
type = string
|
||||||
|
default = "~/.ssh/id_rsa.pub"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "image_name" {
|
||||||
|
description = "Имя образа Ubuntu 20.04"
|
||||||
|
type = string
|
||||||
|
default = "ubuntu-20-202602051631.gite7a38aaf"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "flavor_web" {
|
||||||
|
description = "Flavor для веб-серверов"
|
||||||
|
type = string
|
||||||
|
default = "Basic-1-1-10"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "flavor_bastion" {
|
||||||
|
description = "Flavor для ВМ бастиона"
|
||||||
|
type = string
|
||||||
|
default = "Basic-1-1-10"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "public_subnet_cidr" {
|
||||||
|
description = "CIDR публичной подсети"
|
||||||
|
type = string
|
||||||
|
default = "192.168.1.0/24"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "private_subnet_cidr" {
|
||||||
|
description = "CIDR приватной подсети"
|
||||||
|
type = string
|
||||||
|
default = "192.168.2.0/24"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "volume_size_web" {
|
||||||
|
description = "Размер диска для веб-серверов (ГБ)"
|
||||||
|
type = number
|
||||||
|
default = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "volume_size_bastion" {
|
||||||
|
description = "Размер диска для бастиона (ГБ)"
|
||||||
|
type = number
|
||||||
|
default = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Docker-образ (без логина) ---
|
||||||
|
variable "docker_image" {
|
||||||
|
description = "Полное имя Docker-образа (с тегом)"
|
||||||
|
type = string
|
||||||
|
default = "git.rustprogersteam.ru/black_raven/myresume/resume:latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Аутентификация VKCS ---
|
||||||
|
variable "vkcs_username" {
|
||||||
|
description = "VK Cloud username (из RC-файла)"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vkcs_password" {
|
||||||
|
description = "VK Cloud password"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vkcs_project_id" {
|
||||||
|
description = "VK Cloud project ID (из RC-файла)"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vkcs_region" {
|
||||||
|
description = "VK Cloud region (например, RegionOne или MS1)"
|
||||||
|
type = string
|
||||||
|
default = "RegionOne"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vkcs_auth_url" {
|
||||||
|
description = "VK Cloud Auth URL (например, https://infra.mail.ru:35357/v3/)"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user