462 lines
15 KiB
Markdown
462 lines
15 KiB
Markdown
# Infrastructure Resources & AI Integration Vision
|
||
|
||
**Date**: 24 January 2026
|
||
**Status**: VDC/Edge/vApp resources implementation & AI architecture design
|
||
|
||
## Current State
|
||
|
||
### Resources Implemented
|
||
- ✅ VDC (Virtual Data Center) - service ID 21
|
||
- ✅ Edge Gateway - service ID 22
|
||
- ✅ vApp (Virtual Application) - service ID 26
|
||
- ✅ VM Instance - service ID 28
|
||
|
||
### API Patterns Discovered
|
||
|
||
#### Creation Flow
|
||
```
|
||
1. POST /instances → {serviceId, displayName, descr} → 201 + Location: //{instanceId}
|
||
2. POST /instanceOperations → {instanceUid, operation: "create"} → 201 + Location: //{operationId}
|
||
3. GET /instanceOperations/{operationId}?fields=cfsParams → список параметров
|
||
4. POST /instanceOperationCfsParams → для каждого параметра отправить значение
|
||
5. POST /instanceOperations/{operationId}/run → запустить операцию → 201
|
||
6. POLLING: GET /instanceOperations/{operationId} → проверять operationIsInProgress: false
|
||
7. POLLING: GET /instances/{instanceId} → проверять explainedStatus: "running"
|
||
```
|
||
|
||
#### Critical Bug Fixed
|
||
**Problem**: Provider timeout после 10 минут, хотя VDC создаётся за ~45 секунд.
|
||
|
||
**Root Cause**:
|
||
1. JSON field был `status` вместо `explainedStatus`
|
||
2. Polling проверял только instance, пропуская завершение operation
|
||
|
||
**Solution**:
|
||
```go
|
||
// Исправленная структура
|
||
type InstanceResponse struct {
|
||
Status string `json:"explainedStatus"` // было: json:"status"
|
||
}
|
||
|
||
// Двухэтапный polling
|
||
1. Ждать operationIsInProgress: false (операция завершена)
|
||
2. Проверять explainedStatus: "running" (instance запущен)
|
||
```
|
||
|
||
### Actual Creation Times (from API data)
|
||
- **VDC**: ~43-46 секунд
|
||
- **Edge Gateway**: ~5-10 минут (требует проверки)
|
||
- **vApp**: ~3-5 минут (требует проверки)
|
||
- **VM**: ~5-10 минут
|
||
|
||
### VDC Lifecycle Quirk
|
||
**Delete operation не удаляет VDC**, а переводит в suspend:
|
||
```go
|
||
operationReq := CreateOperationRequest{
|
||
Operation: "suspend", // не "delete"!
|
||
}
|
||
```
|
||
Полное удаление: suspend → ждать 14 дней → удалить вручную через UI.
|
||
|
||
---
|
||
|
||
## Data Sources for Existing Infrastructure
|
||
|
||
### Problem Statement
|
||
Создание VDC+Edge+vApp занимает ~30-40 минут. Если инфраструктура уже существует, не нужно ждать.
|
||
|
||
### Solution: Data Sources
|
||
```text
|
||
# Поиск существующих ресурсов по имени
|
||
data "nubes_vdc" "existing" {
|
||
display_name = "production-vdc"
|
||
}
|
||
|
||
data "nubes_edge" "existing" {
|
||
display_name = "production-edge"
|
||
}
|
||
|
||
data "nubes_vapp" "existing" {
|
||
display_name = "production-vapp"
|
||
}
|
||
|
||
# Создание только VM в существующей инфраструктуре (~5-10 мин вместо ~40)
|
||
# resource "nubes_vm_instance" "web" {
|
||
vapp_uid = data.nubes_vapp.existing.id
|
||
# ...
|
||
}
|
||
```
|
||
|
||
### Flexible Deployment Pattern
|
||
Один конфиг - выбор через переменные:
|
||
```text
|
||
variable "create_vdc" { type = bool }
|
||
variable "create_edge" { type = bool }
|
||
variable "create_vapp" { type = bool }
|
||
|
||
# Условное создание
|
||
resource "nubes_vdc" "new" {
|
||
count = var.create_vdc ? 1 : 0
|
||
# ...
|
||
}
|
||
|
||
# Условный поиск
|
||
data "nubes_vdc" "existing" {
|
||
count = var.create_vdc ? 0 : 1
|
||
display_name = var.existing_vdc_name
|
||
}
|
||
|
||
# Выбор ID
|
||
locals {
|
||
vdc_id = var.create_vdc ? nubes_vdc.new[0].id : data.nubes_vdc.existing[0].id
|
||
}
|
||
```
|
||
|
||
**Use Cases**:
|
||
- `create_vdc=true, create_edge=true, create_vapp=true` → всё с нуля (~30-40 мин)
|
||
- `create_vdc=false, create_edge=false, create_vapp=false` → всё существует (~5-10 мин)
|
||
- `create_vdc=false, create_edge=true, create_vapp=true` → VDC корпоративный, свой Edge+vApp (~15-20 мин)
|
||
|
||
---
|
||
|
||
## AI Integration Vision
|
||
|
||
### Philosophy
|
||
**"Домохозяйка-friendly" облако** - любой человек без технических знаний может создать инфраструктуру описав что ему нужно обычным языком.
|
||
|
||
### Architecture Concept
|
||
|
||
#### 1. Композитный AI-ресурс `nubes_application_stack`
|
||
|
||
**Input - естественный язык**:
|
||
```text
|
||
# resource "nubes_application_stack" "myapp" {
|
||
ai_description = <<-EOT
|
||
Создай простой сайт с базой данных
|
||
EOT
|
||
|
||
vdc_uid = data.nubes_vdc.existing.id
|
||
edge_uid = data.nubes_edge.existing.id
|
||
}
|
||
```
|
||
|
||
**AI парсит через Gemini**:
|
||
```json
|
||
{
|
||
"components": [
|
||
{"type": "vm", "role": "web", "cpu": 2, "ram": 4, "image": "nginx"},
|
||
{"type": "postgres", "version": "14", "storage": 50}
|
||
],
|
||
"network": "shared"
|
||
}
|
||
```
|
||
|
||
**Provider создаёт**:
|
||
1. vApp (контейнер)
|
||
2. VM для nginx (с cloud-init)
|
||
3. VM для PostgreSQL (с cloud-init + конфиг)
|
||
4. Настраивает сеть между ними
|
||
|
||
**Output**:
|
||
```
|
||
Apply complete!
|
||
|
||
Outputs:
|
||
web_vm_ip = "10.0.1.5"
|
||
postgres_connection_string = "postgresql://10.0.1.6:5432/myapp"
|
||
```
|
||
|
||
#### 2. Инкрементальные обновления через естественный язык
|
||
|
||
**Концепция**: История изменений как git changelog
|
||
|
||
```text
|
||
# resource "nubes_application_stack" "myapp" {
|
||
ai_description = <<-EOT
|
||
# День 1 (23.01.2026)
|
||
Создай простой сайт с базой данных
|
||
|
||
# День 7 (30.01.2026)
|
||
+ добавь Redis для кеша
|
||
|
||
# День 14 (06.02.2026)
|
||
+ добавь балансировщик на 2 фронтенда
|
||
|
||
# День 20 (12.02.2026)
|
||
- убери Redis, не пригодился
|
||
EOT
|
||
}
|
||
```
|
||
|
||
**AI видит**:
|
||
- Базовая конфигурация (первая запись)
|
||
- `+` = добавить компонент
|
||
- `-` = удалить компонент
|
||
- Обычный текст = модификация
|
||
|
||
**Provider применяет только delta**:
|
||
- Не трогает существующие VM
|
||
- Создаёт новые компоненты
|
||
- Удаляет ненужные
|
||
|
||
**Преимущества**:
|
||
- Видна эволюция инфраструктуры
|
||
- Audit trail встроен
|
||
- Rollback = удалить последние строки
|
||
- Понятно что и когда менялось
|
||
|
||
#### 3. AI-powered проверка квот и рекомендации
|
||
|
||
**При `terraform plan`**:
|
||
|
||
```go
|
||
func (r *ApplicationStackResource) ModifyPlan(ctx, req, resp) {
|
||
// Парсим AI описание
|
||
aiParams := parseWithGemini(plan.AiDescription.ValueString())
|
||
|
||
// Получаем квоты VDC
|
||
vdcQuotas := getVDCQuotas(plan.VdcUid)
|
||
usedResources := calculateUsedResources(plan.VdcUid)
|
||
available := vdcQuotas - usedResources
|
||
|
||
// Сравниваем с запросом AI
|
||
if aiParams.TotalRAM > available.RAM {
|
||
resp.Diagnostics.AddWarning(
|
||
"Недостаточно ресурсов",
|
||
fmt.Sprintf(`
|
||
AI запрашивает: %d GB RAM
|
||
Доступно в VDC: %d GB
|
||
Используется: %d GB
|
||
|
||
Рекомендации:
|
||
- Уменьшите количество VM
|
||
- Или увеличьте квоту VDC
|
||
- Или используйте другой VDC
|
||
`, aiParams.TotalRAM, available.RAM, usedResources.RAM))
|
||
}
|
||
|
||
// Обратная ситуация - избыточность
|
||
if aiParams.TotalRAM < available.RAM * 0.1 {
|
||
resp.Diagnostics.AddWarning(
|
||
"Избыточная конфигурация",
|
||
fmt.Sprintf(`
|
||
AI запрашивает: %d GB RAM для "%s"
|
||
Доступно: %d GB RAM в VDC
|
||
|
||
Можете смело увеличить ресурсы для лучшей производительности.
|
||
`, aiParams.TotalRAM, aiParams.Purpose, available.RAM))
|
||
}
|
||
}
|
||
```
|
||
|
||
**Вывод при `terraform plan`**:
|
||
```
|
||
╷
|
||
│ Warning: Недостаточно ресурсов
|
||
│
|
||
│ AI запрашивает: 40 GB RAM
|
||
│ Доступно в VDC: 20 GB (квота) - 12 GB (используется) = 8 GB свободно
|
||
│
|
||
│ Рекомендации:
|
||
│ - Уменьшите количество VM до 1-2
|
||
│ - Или увеличьте квоту VDC
|
||
╵
|
||
```
|
||
|
||
#### 4. Gemini API Integration
|
||
|
||
**Technology Stack**:
|
||
- Google Gemini API (есть аккаунт)
|
||
- HTTP JSON API
|
||
- Structured output parsing
|
||
|
||
**Промпт пример**:
|
||
```
|
||
Parse this infrastructure request into JSON:
|
||
"Создай простой сайт с базой данных + добавь Redis для кеша"
|
||
|
||
Return format:
|
||
{
|
||
"components": [
|
||
{"type": "vm", "role": "frontend", "cpu": 2, "ram": 4, "image": "nginx"},
|
||
{"type": "postgres", "version": "14", "storage": 50},
|
||
{"type": "redis", "ram": 2}
|
||
],
|
||
"network": "shared",
|
||
"purpose": "simple website with database and cache"
|
||
}
|
||
```
|
||
|
||
**Provider код**:
|
||
```go
|
||
func parseWithGemini(description string, apiKey string) (*StackSpec, error) {
|
||
reqBody := map[string]interface{}{
|
||
"contents": []map[string]interface{}{
|
||
{"parts": []map[string]string{{"text": buildPrompt(description)}}},
|
||
},
|
||
}
|
||
|
||
resp, err := http.Post(
|
||
"https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key="+apiKey,
|
||
"application/json",
|
||
jsonBody(reqBody),
|
||
)
|
||
|
||
// Parse JSON response
|
||
var result StackSpec
|
||
json.Unmarshal(resp.Body, &result)
|
||
return &result, nil
|
||
}
|
||
```
|
||
|
||
#### 5. Advanced: Schedule & Lifecycle через AI
|
||
|
||
**User input**:
|
||
```text
|
||
# resource "nubes_application_stack" "test_env" {
|
||
ai_description = "Создай тестовое окружение, запусти через 2 дня на 8 часов"
|
||
}
|
||
```
|
||
|
||
**AI парсит**:
|
||
```json
|
||
{
|
||
"schedule": {
|
||
"startAt": "2026-01-26T10:00:00Z",
|
||
"duration": "8h",
|
||
"autoDelete": true
|
||
},
|
||
"components": [...]
|
||
}
|
||
```
|
||
|
||
**Provider behavior**:
|
||
- Записывает метаданные в state
|
||
- Выдаёт Warning о необходимости внешнего оркестратора
|
||
- Или интегрируется с Kubernetes Operator для cron jobs
|
||
|
||
**Full automation** (с Operator):
|
||
```
|
||
Terraform Provider (создание ресурсов)
|
||
↓
|
||
Kubernetes Operator (расписание)
|
||
↓
|
||
CronJob (проверка времени)
|
||
↓
|
||
Terraform (автоматический destroy)
|
||
```
|
||
|
||
---
|
||
|
||
## Unique Value Proposition
|
||
|
||
### Что никто не делает
|
||
|
||
❌ **Pulumi AI** - генерит код, не управляет напрямую
|
||
❌ **Google Duet** - автодополнение, не композитные ресурсы
|
||
❌ **AWS Copilot** - фиксированные шаблоны, не AI парсинг
|
||
|
||
✅ **Наше решение**:
|
||
1. **AI парсинг → композитный ресурс → проверка квот → рекомендации** в одном флоу
|
||
2. **История изменений через естественный язык** как git changelog
|
||
3. **Инкрементальные обновления** - AI понимает delta, Provider применяет только изменения
|
||
4. **"Домохозяйка-friendly"** - нулевой порог входа
|
||
|
||
### Example User Journey
|
||
|
||
**Обычный пользователь без IT знаний**:
|
||
|
||
1. Пишет в Terraform:
|
||
```hcl
|
||
# resource "nubes_application_stack" "myshop" {
|
||
ai_description = "Мне нужен интернет-магазин с корзиной и оплатой картой"
|
||
}
|
||
```
|
||
|
||
2. `terraform plan` показывает:
|
||
```
|
||
AI создаст:
|
||
- 2 VM для фронтенда (nginx) - 2 CPU, 4 GB RAM каждая
|
||
- 1 VM для бэкенда (Node.js) - 4 CPU, 8 GB RAM
|
||
- 1 PostgreSQL для данных - 50 GB storage
|
||
- 1 Redis для сессий - 2 GB RAM
|
||
|
||
Итого: 10 CPU, 18 GB RAM, 50 GB storage
|
||
Доступно в VDC: 20 CPU, 40 GB RAM, 200 GB storage ✅
|
||
```
|
||
|
||
3. `terraform apply` → через 20 минут готовый интернет-магазин
|
||
|
||
4. Через неделю добавляет:
|
||
```hcl
|
||
ai_description = <<-EOT
|
||
Мне нужен интернет-магазин с корзиной и оплатой картой
|
||
+ добавь систему рекомендаций товаров
|
||
EOT
|
||
```
|
||
|
||
5. AI понимает delta, создаёт только ML-сервис, не трогая существующее
|
||
|
||
---
|
||
|
||
## Implementation Roadmap
|
||
|
||
### Phase 1: Infrastructure Resources (Current)
|
||
- [x] VDC, Edge, vApp, VM resources
|
||
- [x] Data sources для существующих ресурсов
|
||
- [x] Правильный polling (operation → instance)
|
||
- [ ] Тестирование Edge/vApp создания
|
||
- [ ] Update/Delete операции для всех ресурсов
|
||
|
||
### Phase 2: AI Integration MVP
|
||
- [ ] Gemini API клиент в Provider
|
||
- [ ] Простой AI-парсинг для VM ресурса
|
||
- [ ] Warning'и с рекомендациями при plan
|
||
- [ ] Проверка квот VDC
|
||
|
||
### Phase 3: Композитный ресурс
|
||
- [ ] `nubes_application_stack` ресурс
|
||
- [ ] AI парсинг complex descriptions
|
||
- [ ] Автоматическое создание vApp + multiple VMs
|
||
- [ ] Cloud-init генерация для разных компонентов
|
||
|
||
### Phase 4: Advanced Features
|
||
- [ ] История изменений (git-like changelog)
|
||
- [ ] Инкрементальные обновления (delta detection)
|
||
- [ ] Интеграция с Kubernetes Operator для scheduling
|
||
- [ ] Terraform module генератор
|
||
|
||
---
|
||
|
||
## Technical Notes
|
||
|
||
### API Quirks
|
||
1. `explainedStatus` не `status` для instance state
|
||
2. `operationIsInProgress` для отслеживания операций
|
||
3. VDC delete = suspend (14 дней до полного удаления)
|
||
4. POST /run возвращает 201 мгновенно, реальная работа начинается после
|
||
|
||
### Performance
|
||
- VDC: 45 сек
|
||
- Edge: 5-10 мин (TBD)
|
||
- vApp: 3-5 мин (TBD)
|
||
- VM: 5-10 мин
|
||
- **Full stack**: ~30-40 мин
|
||
|
||
### Token Management
|
||
- JWT from Keycloak
|
||
- 2-hour expiry
|
||
- Stored in ~/.nubes_token
|
||
- Format: raw JWT (без "Bearer" prefix)
|
||
- Требует trim whitespace
|
||
|
||
---
|
||
|
||
## Questions for Product Team
|
||
|
||
1. **AI API Key**: где хранить? Provider config? Environment variable? Terraform Cloud?
|
||
2. **Scheduling**: нужен ли Kubernetes Operator или достаточно метаданных в state?
|
||
3. **Billing**: как считать стоимость AI-созданных ресурсов для показа пользователю?
|
||
4. **Templates**: создавать ли библиотеку готовых AI-промптов? ("WordPress site", "Django app", etc.)
|
||
5. **Validation**: нужна ли human-approval после AI парсинга перед apply?
|