Ведущий: "Добро пожаловать на воркшоп! За следующие 20 минут мы развернём квиз-приложение в облаке Cloud.ru — от промпта в нейросети до работающего приложения."
Цели воркшопа:
- Сгенерировать Terraform-код с помощью нейросети
- Создать идентичные test/prod окружения одной командой
- Освоить безопасное изменение конфигурации через Git workflow с Ansible
- Автоматически развернуть приложение без ручной настройки серверов
Для подключения к VM по SSH нужен SSH-ключ. Если его нет — создайте:
# Создание SSH-ключа (если ещё нет)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Нажмите Enter для всех вопросов (или задайте пароль)
# Ключ будет создан в ~/.ssh/id_ed25519
# Публичный ключ ~/.ssh/id_ed25519.pub добавится на VM автоматически через cloud-initВажно: путь к ключу
~/.ssh/id_ed25519используется во всех командах Ansible. Если вы создали ключ с другим именем — замените в командах.
- Открывает нейросеть (ChatGPT/GigaChat/Claude)
- Показывает промпт:
Создай Terraform-код для развёртывания ВМ в облаке Cloud.ru Evolution:
- Провайдер: cloud.ru с endpoint api.cloud.ru
- Проект: использовать переменные
- VPC с подсетью
- Security group с правилами для SSH (22) и HTTP (80/443/5000)
- Ubuntu 22.04 ВМ с минимальными ресурсами
- Output: IP адрес, имя ВМ
- Используй locals для настроек
- Демонстрирует результат — готовый
.tfфайл
- Наблюдают процесс генерации
- Записывают ключевые моменты промптинга
terraform/
├── terraform.tf # Основная конфигурация
├── variables.tf # Переменные
├── test.tfvars # Настройки тестового
├── prod.tfvars # Настройки продакшн
└── secrets.tfvars # Секреты (не в git)
test.tfvars:
environment = "test"
vm_name = "quiz-test"
flavor = "gen-1-1"
zone = "ru.AZ-1"prod.tfvars:
environment = "prod"
vm_name = "quiz-prod"
flavor = "gen-1-1"
zone = "ru.AZ-1"Что такое workspaces: Изолированные состояния (tfstate) для разных окружений. Один код — разные ВМ. State хранится локально в директории
terraform.tfstate.d/(test/ и prod/ поддиректории).
⚠️ ВАЖНО: Перед каждымterraform applyобязательно проверяйте текущий workspace командойterraform workspace show. Если работаете с test — сначала переключитесь:terraform workspace select test. Применение к неправильному workspace может привести к созданию ресурсов в не том окружении или ошибкам "already exists".
# 1. Инициализация
terraform init
# 2. Тестовое окружение
terraform workspace new test
terraform apply -var-file="test.tfvars" -var-file="secrets.tfvars"
# 3. Продакшн окружение
terraform workspace new prod
terraform apply -var-file="prod.tfvars" -var-file="secrets.tfvars"
# 4. Переключение между окружениями
terraform workspace select test
terraform workspace select prodКоманды для управления:
terraform workspace list # посмотреть все workspaces
terraform workspace show # какой сейчас активен (ОБЯЗАТЕЛЬНО проверять перед apply!)
terraform workspace select test # переключиться на test
terraform workspace select prod # переключиться на prod
⚠️ ВАЖНО: После создания ВМ Ubuntu выполняет полное обновление дистрибутива. Это занимает 3-5 минут! Прежде чем подключаться по SSH и устанавливать пакеты через Ansible, обязательно дождитесь завершения обновления.
Опционально: для генерации
inventory.iniможно использовать скрипт:scripts/generate-inventory.sh ~/.ssh/id_ed25519
# Переключаемся на test и проверяем
terraform workspace select test
terraform workspace show # должно показать: test
# Получаем IP test VM
terraform output external_ip # проверим, что это test
# Сохраняем IP в переменную
TEST_IP=$(terraform output -raw external_ip)
# Деплой в test
ansible-playbook -i "${TEST_IP}," ansible/playbook.yml \
-u ubuntu --private-key ~/.ssh/id_ed25519 \
-e app_environment=test# Переключаемся на prod и проверяем
terraform workspace select prod
terraform workspace show # должно показать: prod
# Получаем IP prod VM
terraform output external_ip # проверим, что это prod
# Сохраняем IP в переменную
PROD_IP=$(terraform output -raw external_ip)
# Деплой в prod
ansible-playbook -i "${PROD_IP}," ansible/playbook.yml \
-u ubuntu --private-key ~/.ssh/id_ed25519 \
-e app_environment=prod- test:
test-quiz-vm— 1 CPU, 1 GB RAM - prod:
prod-quiz-vm— 1 vCPU, 1 GB RAM
Обе ВМ идентичной структуры и размера (gen-1-1: 1 vCPU, 1 GB RAM).
Ручные изменения на серверах — это хаос:
- Кто что изменил — непонятно
- Откат занимает часы
- Нет аудита
На воркшопе (упрощённо):
1. Создаём branch → feature/change-test-colors
2. Меняем CSS → quiz-app/static/style.css
3. Git commit → локально
4. Ansible деплой → только в test
В реальной жизни:
1. Создаём branch → feature/change-test-colors
2. Меняем код → quiz-app/static/style.css
3. Git commit + push → Review в PR
4. Merge → CI/CD деплоит в test
5. Проверка → тестирование в test
6. CI/CD деплой → в prod
| Параметр | test | prod |
|---|---|---|
| Цвета (одинаковые) | Зелёные (#11998e → #38ef7d) | Зелёные (#11998e → #38ef7d) |
| Flavor | gen-1-1 (1 vCPU, 1 GB RAM) | gen-1-1 (1 vCPU, 1 GB RAM) |
После деплоя откройте в браузере:
- test:
http://<TEST_VM_IP>:5000— зелёный квиз - prod:
http://<PROD_VM_IP>:5000— зелёный квиз (пока цвета одинаковые)
IP ВМ можно получить:
terraform workspace select test
terraform output external_ip
terraform workspace select prod
terraform output external_ipПокажем главное преимущество GitOps — изолированные изменения:
Шаг 1: Изначально цвета одинаковые
- test: зелёные (#11998e → #38ef7d)
- prod: зелёные (#11998e → #38ef7d)
Шаг 2: Создаём ветку для изменения test
# Переключаемся на main
git checkout main
# Создаём ветку для изменения цветов (или используем существующую)
git checkout -b feature/change-test-colors
# Если ветка уже существует:
# git checkout feature/change-test-colorsШаг 3: Меняем цвет в CSS-файле
Основной CSS файл: quiz-app/static/style.css
Сейчас цвета зелёные: #11998e → #38ef7d
Поменяйте 2 цвета зелёного градиента на 2 цвета фиолетового:
- Было:
#11998e → #38ef7d - Стало:
#667eea → #764ba2
vim quiz-app/static/style.css
# Замените #11998e на #667eea
# Замените #38ef7d на #764ba2Шаг 4: Смотрим diff — видим что изменилось
git diff
# Показать изменения конкретного файла
git diff quiz-app/static/style.cssШаг 5: Коммитим изменения
git add quiz-app/
git commit -m "Change test colors to purple"Шаг 6: Деплоим только в test (prod не трогаем)
⚠️ ВАЖНО: После создания ВМ Ubuntu выполняет полное обновление дистрибутива. Это занимает 3-5 минут! Прежде чем подключаться по SSH и устанавливать пакеты через Ansible, обязательно дождитесь завершения обновления.
# Получаем IP test VM
terraform workspace select test
TEST_VM_IP=$(terraform output -raw external_ip)
echo $TEST_VM_IP
# Деплоим в test
ansible-playbook -i "${TEST_VM_IP}," ansible/playbook.yml \
-u ubuntu --private-key ~/.ssh/id_ed25519 \
-e app_environment=testШаг 7: Проверяем результат
- test: http://<TEST_VM_IP>:5000 — изменился на фиолетовый (#667eea)
- prod: http://<PROD_VM_IP>:5000 — остался зелёным (#11998e → #38ef7d) — без изменений
Откройте оба URL в браузере — видим разницу! Это и есть GitOps в действии.
Цвета приложения задаются в двух местах:
-
В CSS файле (
quiz-app/static/style.css) — общие стили для всех окружений:- Градиент фона
body - Градиент кнопок
.btn - Градиент прогресс-бара
.progress-bar - Градиент круга результатов
.score-circle
Это статические цвета — одинаковые для test и prod.
- Градиент фона
-
В HTML шаблонах — цвета badge (плашки) с надписью TEST/PROD:
- TEST: синий фон (#1D4ED8), белый текст
- PROD: красный фон (#B91C1C), белый текст
Эти цвета динамические — определяются переменной
app_envчерез Jinja2.
Workflow:
- Ansible получает
app_environmentиз переменной - Передаёт в Flask через переменную окружения
APP_ENV - Flask рендерит шаблоны с
app_env→ badge: TEST или PROD - Общие CSS стили применяются ко всем окружениям одинаково
Участники научились:
- ✓ Генерировать Terraform-код через AI
- ✓ Создавать идентичные окружения через workspaces
- ✓ Управлять конфигурацией через Git + Ansible
- ✓ Развёртывать приложения с разными environments
- ✓ Визуально различать test и prod
За 20 минут вместо ручной настройки (2-4 часа) участники получили:
- Две готовые ВМ (test + prod)
- Работающее квиз-приложение с разными цветами
- Понимание полного цикла IaC + GitOps
- E2E.md — Продвинутое руководство с промптами
- Документация Cloud.ru
- Документация Terraform
- Документация Ansible
# 1. Подготовка
git clone <REPO_URL>
cd <REPO_NAME>
cp secrets.tfvars.example secrets.tfvars
# Редактирование secrets.tfvars: project_id, auth_key_id, auth_secret
# 2. Terraform
terraform init
terraform workspace new test
terraform apply -var-file="secrets.tfvars" -var-file="test.tfvars"
terraform workspace new prod
terraform apply -var-file="secrets.tfvars" -var-file="prod.tfvars"
# Опционально: генерация inventory.ini
# scripts/generate-inventory.sh ~/.ssh/id_ed25519
# 3. Деплой в test
terraform workspace select test
terraform workspace show # проверить: test
TEST_IP=$(terraform output -raw external_ip)
ansible-playbook -i "${TEST_IP}," ansible/playbook.yml \
-u ubuntu --private-key ~/.ssh/id_ed25519 -e app_environment=test
# 4. Деплой в prod
terraform workspace select prod
terraform workspace show # проверить: prod
PROD_IP=$(terraform output -raw external_ip)
ansible-playbook -i "${PROD_IP}," ansible/playbook.yml \
-u ubuntu --private-key ~/.ssh/id_ed25519 -e app_environment=prod
# 5. Проверка
open http://${TEST_IP}:5000 # test
open http://${PROD_IP}:5000 # prod| Проблема | Решение |
|---|---|
| Terraform не инициализируется | Проверьте terraform.tf и провайдер |
| Не подключается по SSH | Проверьте security group и IP |
| Ansible не работает | Проверьте доступ по ключу: ssh -i ~/.ssh/id_ed25519 ubuntu@IP |
| Приложение не запускается | Проверьте логи: journalctl -u quiz-app -n 50 |
| Цвета не меняются | Проверьте APP_ENV: echo $APP_ENV |
| Не работает деплой | Проверьте переменную app_environment: ansible ... -e app_environment=test |