Files
tf_provider/docs/60_strategy/complex_provisioning_workflow.md
T
Repinoid 0464a30642 docs(strategy): оркестрация взаимозависимых ресурсов и паттерн привязок
- complex_provisioning_workflow.md — цепочка vcOrg -> vcVdc -> vcNsxt -> Штурвал,
  включая modify-шаги и пошаговые модификации
- shturval_dev_provisioning_spec.md — точные параметры и ID операций DEV-стенда
  для цепочки развёртывания k8s_sthutrval_cluster
- terraform_association_pattern_and_pipeline.md — Resource Association Pattern
  (разделение сущности и ресурсов-привязок/модификаций)
2026-09-18 18:44:36 +03:00

8.7 KiB
Raw Blame History

Оркестрация взаимозависимых ресурсов и пошаговых модификаций (на примере Штурвал)

1. Контекст и проблематика

Исходная последовательность развертывания

Для развертывания инстанса сервиса Штурвал требуется подготовить сетевую и виртуальную инфраструктуру, состоящую из трёх взаимозависимых компонентов:

  1. vcOrg/create — создание виртуальной организации (vCD Org).
  2. vcVdc/create — создание виртуального дата-центра (vDC) внутри организации.
  3. vcNsxt/create — создание сетевого шлюза NSX-T (включение AVI, выделение 4 Service Engine).
  4. vcOrg/modify — модификация организации (добавление 3 внешних IP-адресов).
  5. vcNsxt/modify — повторная модификация NSX-T (включение SNAT, привязка выделенного ipSpace из vcOrg).
  6. Штурвал/create — создание кластера сервиса «Штурвал».

В чём архитектурная сложность для Terraform

В стандартной декларативной модели Terraform каждый ресурс управляется монолитно: один блок resource соответствует полному жизненному циклу одной сущности (Create -> Read -> Update -> Delete).

В описанном сценарии возникает чередующаяся (interleaved) зависимость:

  • vcOrg должен существовать до vcVdc и vcNsxt.
  • Но добавление IP-адресов в vcOrg (шаг 4) и настройка SNAT в vcNsxt (шаг 5) должны выполняться после создания базового vcNsxt (шаг 3).
  • Штурвал (шаг 6) требует, чтобы и IP-адреса, и SNAT уже были применены.

Если пытаться упаковать шаги 1 и 4 в один ресурс cloud_vc_org, а шаги 3 и 5 — в один cloud_vc_nsxt, возникает тупик в графе зависимостей Terraform (Directed Acyclic Graph, DAG), либо API вернет ошибку из-за несвоевременного вызова параметров.


2. Архитектурное решение: Паттерн отдельных ресурсов модификации (Subresource / Action Pattern)

Канонический подход в экосистеме Terraform (аналогично aws_security_group + aws_security_group_rule, aws_vpc + aws_route) — декомпозиция отложенных действий и привязок в отдельные управляемые ресурсы провайдера.

Структура ресурсов

  1. Базовые ресурсы жизненного цикла (Core Instances):
    • cloud_vc_org — создает и держит базу организации.
    • cloud_vc_vdc — создает VDC внутри Org.
    • cloud_vc_nsxt — создает NSX-T шлюз (AVI, 4 SE).
  2. Ресурсы отложенной конфигурации / модификаций (Action / Subresources):
    • cloud_vc_org_ip_allocation (или cloud_vc_org_modify_ip) — управляет пулом выделенных IP-адресов организации.
    • cloud_vc_nsxt_snat (или cloud_vc_nsxt_modify_snat) — управляет правилом SNAT и связкой с ip_space.
  3. Целевой сервис:
    • cloud_shturval — разворачивает кластер Штурвал.

Пример манифеста HCL

# 1. Создание организации
resource "cloud_vc_org" "org" {
  name = "demo-org"
}

# 2. Создание VDC
resource "cloud_vc_vdc" "vdc" {
  name   = "demo-vdc"
  org_id = cloud_vc_org.org.id
}

# 3. Создание NSX-T (включение AVI и 4 Service Engine)
resource "cloud_vc_nsxt" "nsxt" {
  name            = "demo-nsxt"
  vdc_id          = cloud_vc_vdc.vdc.id
  enable_avi      = true
  service_engines = 4
}

# 4. Модификация vcOrg: добавление 3 IP после готовности NSX-T
resource "cloud_vc_org_ip_allocation" "org_ips" {
  org_id   = cloud_vc_org.org.id
  ip_count = 3

  # Явная зависимость гарантирует выполнение после создания NSX-T
  depends_on = [cloud_vc_nsxt.nsxt]
}

# 5. Модификация vcNsxt: включение SNAT с ipSpace из vcOrg
resource "cloud_vc_nsxt_snat" "snat" {
  nsxt_id  = cloud_vc_nsxt.nsxt.id
  ip_space = cloud_vc_org_ip_allocation.org_ips.ip_space_id
  enabled  = true
}

# 6. Создание сервиса Штурвал
resource "cloud_shturval" "cluster" {
  name   = "demo-shturval"
  vdc_id = cloud_vc_vdc.vdc.id

  # Зависит от полной готовности сетевой связки
  depends_on = [
    cloud_vc_nsxt_snat.snat,
    cloud_vc_org_ip_allocation.org_ips
  ]
}

Terraform самостоятельно строит идеальный граф исполнения:

graph TD
    A[cloud_vc_org] --> B[cloud_vc_vdc]
    B --> C[cloud_vc_nsxt]
    C --> D[cloud_vc_org_ip_allocation]
    D --> E[cloud_vc_nsxt_snat]
    E --> F[cloud_shturval]

3. Интеграция в провайдер

Реализация через генератор провайдера

Согласно политике репозитория (Immutability Policy), код конкретных ресурсов не правится вручную, а генерируется:

  1. В схему генератора добавляются описания новых сущностей:
    • Тип action или subresource для вызова эндпоинтов модификации.
    • Контракты входных/выходных атрибутов (org_id, ip_count, ip_space_id, nsxt_id, enabled).
  2. Кодогенератор генерирует стандартные CRUD-структуры Terraform Plugin Framework / SDK.

Жизненный цикл ресурсов модификации

  • Create:
    • Вызывает соответствующий API-метод (POST /api/v1/vcOrg/{id}/modify или /api/v1/vcNsxt/{id}/modify).
    • Дожидается применения задачи (task tracking / polling).
    • Сохраняет идентификатор операции или полученный ip_space_id в Terraform State.
  • Read:
    • Запрашивает текущее состояние родительского ресурса через GET API.
    • Проверяет, выделены ли IP / активен ли SNAT.
  • Update:
    • Если меняется количество IP или настройки SNAT — отправляет повторный запрос на модификацию.
  • Delete (terraform destroy):
    • При уничтожении инфраструктуры порядок разворачивается в обратную сторону.
    • Сначала удаляется cloud_shturval.
    • Затем cloud_vc_nsxt_snat отключает SNAT.
    • Затем cloud_vc_org_ip_allocation освобождает выделенные IP.
    • И только затем удаляются базовые vcNsxt, vcVdc и vcOrg.

4. Альтернативные подходы

  1. Smart Provider (комбинированный Create):
    • Если API позволяет вызывать шаги последовательно внутри одного HTTP-сеанса бэкенда, провайдер мог бы скрыть это внутри Create ресурса cloud_shturval.
    • Минус: теряется гибкость и прозрачность статусов; сбой на промежуточном этапе оставляет "зависшие" ресурсы в облаке без записи в tfstate.
  2. Модули Terraform (Module Wrapper):
    • Описанная выше структура ресурсов упаковывается в официальный Terraform-модуль terraform-nubes-shturval, скрывая сложность связей от конечного пользователя и предоставляя простой интерфейс ввода параметров.