add: documentation
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# VM Resource Best Practices
|
||||
|
||||
## Критичные параметры для устойчивого создания VM
|
||||
|
||||
### 1. JSON Параметры - ОБЯЗАТЕЛЬНО использовать `jsonencode()`
|
||||
|
||||
**❌ НЕПРАВИЛЬНО:**
|
||||
```text
|
||||
resource "nubes_vm" "web" {
|
||||
access_port_list = "22,80,443" # ОШИБКА: не JSON!
|
||||
access_ip_list = "" # ОШИБКА: пустая строка!
|
||||
}
|
||||
```
|
||||
|
||||
**✅ ПРАВИЛЬНО:**
|
||||
```text
|
||||
resource "nubes_vm" "web" {
|
||||
access_port_list = jsonencode(["22", "80", "443"])
|
||||
access_ip_list = jsonencode(["1.2.3.4", "10.0.0.0/8"])
|
||||
|
||||
# Если нужен доступ отовсюду - не указывайте параметр:
|
||||
# access_ip_list не указан = доступ с 0.0.0.0/0
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Валидация на этапе plan
|
||||
|
||||
Провайдер автоматически проверит:
|
||||
- ✅ `access_port_list` - валидный JSON массив
|
||||
- ✅ `access_ip_list` - валидный JSON массив (если указан)
|
||||
- ✅ `vm_cpu`, `vm_ram`, `vm_disk` >= 1
|
||||
- ✅ `image_vm` - один из разрешённых образов
|
||||
|
||||
**Ошибка при некорректном формате:**
|
||||
```
|
||||
Error: Invalid JSON Array
|
||||
│
|
||||
│ with nubes_vm.web,
|
||||
│ on main.tf line 10:
|
||||
│ 10: access_port_list = "22,80"
|
||||
│
|
||||
│ Value must be a valid JSON array: invalid character ',' after top-level value
|
||||
```
|
||||
|
||||
### 3. Default значения
|
||||
|
||||
| Параметр | Default | Поведение |
|
||||
|----------|---------|-----------|
|
||||
| `access_ip_list` | `["0.0.0.0/0"]` | Если не указан или пустой - доступ отовсюду |
|
||||
| `deletion_protection` | `true` | При `terraform destroy` ресурс удаляется только из state, не из облака |
|
||||
|
||||
### 4. Специальные значения
|
||||
|
||||
#### `ip_space_name`
|
||||
- `"no-needed"` - не выделять внешний IP
|
||||
- Любое другое значение - имя ipSpace для публикации VIP
|
||||
|
||||
#### `access_ip_list`
|
||||
- **Не указан** → доступ с 0.0.0.0/0
|
||||
- `jsonencode(["1.2.3.4"])` → доступ только с указанного IP
|
||||
- `jsonencode(["10.0.0.0/8", "192.168.0.0/16"])` → доступ с нескольких подсетей
|
||||
|
||||
### 5. Lifecycle операции
|
||||
|
||||
#### Create
|
||||
1. Создаётся instance в API
|
||||
2. Создаётся operation "create"
|
||||
3. Отправляются все параметры (включая defaults)
|
||||
4. **Важно**: Если `access_ip_list` не задан, отправляется `["0.0.0.0/0"]`
|
||||
5. Запускается выполнение через `/run`
|
||||
6. Polling до завершения (статус `running`)
|
||||
|
||||
#### Update (Modify)
|
||||
Модифицируемые поля:
|
||||
- `vm_cpu` - можно увеличивать/уменьшать
|
||||
- `vm_ram` - можно увеличивать/уменьшать
|
||||
- `vm_disk` - **только увеличение!** (нельзя уменьшить)
|
||||
- `ip_space_name` - изменение внешнего IP
|
||||
- `access_ip_list` - изменение белого списка
|
||||
- `access_port_list` - изменение портов
|
||||
- `need_add_zabbix_template` - включить/выключить мониторинг
|
||||
|
||||
#### Delete
|
||||
- **С `deletion_protection = true`** (default): Ресурс удаляется из Terraform state, остаётся в облаке
|
||||
- **С `deletion_protection = false`**: Отправляется операция `suspend` (карантин 14 дней), затем ресурс удаляется из state
|
||||
|
||||
### 6. Известные ловушки (из HAR анализа)
|
||||
|
||||
#### Проблема: VM создалась, но FW зависает
|
||||
**Причина**: Пустая строка в `accessIpList` или `accessPortList`
|
||||
|
||||
**Решение**: Провайдер теперь автоматически заменяет:
|
||||
- Пустой `access_ip_list` → `["0.0.0.0/0"]`
|
||||
- Пустой `vm_disk` → параметр не отправляется
|
||||
|
||||
#### Проблема: ColdFusion Type Mismatch Error
|
||||
**Причина**: Сервер получил массив вместо GUID или наоборот
|
||||
|
||||
**Решение**: Провайдер использует динамическое мапирование параметров по `Code` (как в Postgres ресурсе)
|
||||
|
||||
### 7. Debugging
|
||||
|
||||
При проблемах с созданием VM проверьте:
|
||||
|
||||
1. **Terraform logs** (уровень TRACE):
|
||||
```bash
|
||||
TF_LOG=TRACE terraform apply
|
||||
```
|
||||
|
||||
2. **Параметры операции** в выводе:
|
||||
```
|
||||
submitVMOperationParams: sending accessIpList (ID 413) = ["0.0.0.0/0"]
|
||||
```
|
||||
|
||||
3. **Статус операции** в Read:
|
||||
```
|
||||
Operation Status: isSuccessful=false, isInProgress=true
|
||||
Stages: [{"stage":"Добавление правил FW","isSuccessful":false}]
|
||||
```
|
||||
|
||||
### 8. Пример корректной конфигурации
|
||||
|
||||
```text
|
||||
resource "nubes_vm" "app_server" {
|
||||
display_name = "app-prod-01"
|
||||
description = "Application server"
|
||||
|
||||
vapp_uid = nubes_vapp.my_app.id
|
||||
vm_name = "app-prod-01"
|
||||
|
||||
# Ресурсы (обязательно >= 1)
|
||||
vm_cpu = 2
|
||||
vm_ram = 4
|
||||
vm_disk = 50 # GB, можно только увеличивать
|
||||
|
||||
# Образ (проверяется валидатором)
|
||||
image_vm = "Ubuntu_22-20G"
|
||||
|
||||
# SSH доступ
|
||||
user_login = "ubuntu"
|
||||
user_public_key = file("~/.ssh/id_ed25519.pub")
|
||||
|
||||
# Firewall (JSON массивы!)
|
||||
access_port_list = jsonencode(["22", "80", "443"])
|
||||
access_ip_list = jsonencode(["1.2.3.4/32", "10.0.0.0/8"])
|
||||
|
||||
# Внешний IP
|
||||
ip_space_name = "k8s-3.ext.nubes.ru" # или "no-needed"
|
||||
|
||||
# Мониторинг
|
||||
need_add_zabbix_template = true
|
||||
|
||||
# Cloud-init (опционально)
|
||||
cloud_init = <<-EOT
|
||||
#cloud-config
|
||||
packages:
|
||||
- nginx
|
||||
runcmd:
|
||||
- systemctl start nginx
|
||||
EOT
|
||||
|
||||
# Защита от удаления
|
||||
deletion_protection = true # default, можно не указывать
|
||||
}
|
||||
```
|
||||
|
||||
## Миграция с предыдущих версий
|
||||
|
||||
Если у вас есть конфигурации без JSON валидации:
|
||||
|
||||
1. **Проверьте все `access_port_list` и `access_ip_list`**
|
||||
2. **Оберните в `jsonencode()`**
|
||||
3. **Запустите `terraform plan`** - валидаторы покажут ошибки
|
||||
4. **Исправьте до применения**
|
||||
|
||||
Провайдер версии ≥ v1.1.0 отклонит некорректные конфигурации на этапе plan, что **предотвратит зависание на FW правилах**.
|
||||
Reference in New Issue
Block a user