К основному содержимому

Proxmox REST API и автоматизация: управление через скрипты

Proxmox VE · 19.04.2026 · 6 мин чтения
Иллюстрация к статье «Proxmox REST API и автоматизация: управление через скрипты»

Proxmox VE предоставляет полноценный REST API, через который доступны все операции — от создания VM до управления кластером. Это основа для интеграции с Terraform, Ansible, CI/CD и собственными скриптами.

МетодПрименениеСрок действия
API TokenСкрипты, автоматизация, CI/CDБессрочно (до отзыва)
Session CookieВеб-интерфейс, разовые запросы2 часа

Создание API-токена

# Создать пользователя для автоматизации
pveum user add automation@pve --password AutoPass123

# Назначить права
pveum aclmod / --users automation@pve --roles PVEVMAdmin

# Создать API-токен (без привилегий суперпользователя)
pveum user token add automation@pve mytoken --privsep 0

# Вывод: automation@pve!mytoken = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Примеры запросов через curl

>TOKEN="automation@pve!mytoken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
HOST="https://192.168.1.100:8006/api2/json"

# Список нод кластера
curl -s -k -H "Authorization: PVEAPIToken=$TOKEN" "$HOST/nodes" | python3 -m json.tool

# Список VM на ноде pve
curl -s -k -H "Authorization: PVEAPIToken=$TOKEN" "$HOST/nodes/pve/qemu"

# Запустить VM 100
curl -s -k -X POST -H "Authorization: PVEAPIToken=$TOKEN" "$HOST/nodes/pve/qemu/100/status/start"

# Остановить VM
curl -s -k -X POST -H "Authorization: PVEAPIToken=$TOKEN" "$HOST/nodes/pve/qemu/100/status/stop"

# Создать снапшот
curl -s -k -X POST   -H "Authorization: PVEAPIToken=$TOKEN"   -d "snapname=api-test&description=Created+via+API"   "$HOST/nodes/pve/qemu/100/snapshot"

Python SDK для Proxmox

>from proxmoxer import ProxmoxAPI

proxmox = ProxmoxAPI(
    '192.168.1.100',
    user='automation@pve',
    token_name='mytoken',
    token_value='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
    verify_ssl=False
)

# Список всех VM
for vm in proxmox.nodes('pve').qemu.get():
    print(f"VM {vm['vmid']}: {vm['name']} - {vm['status']}")

# Создать снапшот
proxmox.nodes('pve').qemu(100).snapshot.post(
    snapname='python-snap',
    description='Created via Python SDK'
)

# Запустить VM
proxmox.nodes('pve').qemu(100).status.start.post()
Установка SDK: pip install proxmoxer requests. Официальная документация API доступна на вашем сервере: https://YOUR-PVE:8006/pve-docs/api-viewer/

Terraform провайдер Proxmox

>terraform {
  required_providers {
    proxmox = {
      source  = "bpg/proxmox"
      version = "~> 0.50"
    }
  }
}

provider "proxmox" {
  endpoint  = "https://192.168.1.100:8006/"
  api_token = "automation@pve!mytoken=xxxxxxxx..."
  insecure  = true
}

resource "proxmox_virtual_environment_vm" "ubuntu" {
  name      = "tf-ubuntu"
  node_name = "pve"
  vm_id     = 300

  clone {
    vm_id = 100  # ID шаблона
    full  = false
  }

  cpu { cores = 2 }
  memory { dedicated = 2048 }

  network_device {
    bridge = "vmbr0"
    model  = "virtio"
  }
}

Частые ошибки при работе с Proxmox API

401 Unauthorized: permission denied - invalid PVE ticket

596 Connection reset by peer / SSL_ERROR

Parameter verification failed: vmid: value does not look like a valid VM ID

403 Forbidden: Permission check failed (/vms/100, VM.PowerMgmt)
СообщениеПричинаРешение
401 Unauthorized: invalid PVE ticketAPI-токен указан неверно или отозван, либо забыт префикс PVEAPIToken= в заголовкеПроверить формат заголовка: Authorization: PVEAPIToken=user@realm!tokenid=UUID
596 Connection reset / SSL_ERRORКлиент обращается по HTTP вместо HTTPS, либо самоподписанный сертификат не принят без флага verify_ssl=FalseИспользовать https:// и флаг -k в curl или verify_ssl=False в proxmoxer для тестового стенда
Parameter verification failed: vmidID виртуальной машины передан как строка с недопустимыми символами или вне диапазонаУказывать vmid только числом в допустимом диапазоне, без кавычек в JSON-теле запроса
403 Forbidden: Permission check failedУ пользователя API-токена нет роли с нужным правом (например, VM.PowerMgmt) на этом путиНазначить роль через pveum aclmod на путь /vms/VMID или общий /, не только создать токен

API-токен против Terraform-провайдера: что выбрать

КритерийПрямой API-токен (curl/Python)Terraform-провайдер
Разовые операции и скриптыБыстро, минимум зависимостейИзбыточно для одной команды
Воспроизводимая инфраструктура из кодаНужно писать идемпотентность вручнуюШтатно — state-файл отслеживает изменения
Откат к предыдущей конфигурацииВручную, через отдельные API-вызовыterraform apply с предыдущим state
Порог входа для командыНиже — обычный HTTP-клиентВыше — нужно знать HCL и жизненный цикл Terraform

Когда автоматизация через API не подходит

  • Разовая ручная задача, которую проще выполнить через веб-интерфейс за одну минуту — оборачивать её в скрипт с аутентификацией не окупается
  • В команде никто не поддерживает получившиеся скрипты после ухода автора — необслуживаемая автоматизация опаснее, чем её отсутствие, особенно рядом с status/start и status/stop
  • Нужна визуальная проверка состояния кластера перед каждым действием (соседние ноды, свободное место) — API не показывает это так же наглядно, как веб-интерфейс
  • Инфраструктура меняется настолько редко, что Terraform state будет расходиться с реальностью между запусками — в этом случае ручные операции надёжнее автоматизации, за которой не следят

Проверка, что автоматизация работает верно

# Токен действителен и видит кластер
curl -s -k -H "Authorization: PVEAPIToken=$TOKEN" "$HOST/version"

# Права токена ограничены ожидаемым набором
pveum user permissions automation@pve

# Список задач, запущенных через API, для сверки с логом скрипта
pvesh get /nodes/pve/tasks --limit 10
  1. Выполните запрос к /version без привязки к конкретной VM — если он возвращает 200, токен рабочий на базовом уровне
  2. Сверьте фактические права токена командой pveum user permissions с тем, что ожидалось при создании — лишние права проще всего убрать сразу
  3. После выполнения скрипта проверьте список задач в /nodes/NODE/tasks — каждое действие API должно там отражаться с итоговым статусом OK
  4. Для Terraform выполните terraform plan без применения и убедитесь, что он не показывает неожиданных изменений на уже существующих ресурсах

Ограничение прав токена по ролям и ACL разбирает статья пользователи, роли и ACL в Proxmox, а базовую защиту самого веб-интерфейса панели — материал двухфакторная защита панели Proxmox.

Частые вопросы

Обходит ли API-токен двухфакторную аутентификацию, включённую для входа в веб-интерфейс Proxmox?

API-токен и вход в веб-интерфейс — это разные механизмы аутентификации: токен имеет собственный секрет и проверяется отдельно от сессии браузера, поэтому формально он не «обходит» двухфакторную защиту, а просто работает по другому пути входа, для которого эта защита не предусмотрена. Именно поэтому права и срок жизни такого токена стоит ограничивать особенно внимательно.

Что безопаснее: выдать токену автоматизации права суперпользователя или ограниченную роль?

Ограниченная роль безопаснее практически всегда: токен создаётся под конкретную задачу, и ему стоит выдавать только те права, которые реально нужны скрипту, через назначение роли на конкретный путь, а не на корень дерева ресурсов. Права суперпользователя превращают утечку одного токена в компрометацию всего кластера целиком, тогда как узкая роль ограничивает ущерб заранее понятными рамками.

Нужно ли передавать пароль пользователя при каждом запросе, если используется API-токен?

Нет, в этом и смысл токена: однажды созданное значение подставляется в заголовок запроса и действует без ввода пароля, пока его явно не отозвали. Пароль нужен только для сессионного входа через cookie, у которого ограниченный срок действия, тогда как токен создан специально для скриптов и автоматизации, где повторный ручной ввод пароля был бы неудобен и небезопасен.

Стоит ли переходить на Terraform, если прямые вызовы API через curl или Python уже работают?

Если текущие скрипты решают разовые задачи и ими кто-то постоянно занимается, менять их на Terraform не обязательно. Переход оправдан, когда инфраструктура должна воспроизводиться по описанию из кода, нужен откат к прежней конфигурации и отслеживание состояния, — тогда state-файл Terraform берёт на себя то, что иначе пришлось бы реализовывать вручную поверх прямых вызовов API.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке