- 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 (разделение сущности и ресурсов-привязок/модификаций)
8.7 KiB
Оркестрация взаимозависимых ресурсов и пошаговых модификаций (на примере Штурвал)
1. Контекст и проблематика
Исходная последовательность развертывания
Для развертывания инстанса сервиса Штурвал требуется подготовить сетевую и виртуальную инфраструктуру, состоящую из трёх взаимозависимых компонентов:
vcOrg/create— создание виртуальной организации (vCD Org).vcVdc/create— создание виртуального дата-центра (vDC) внутри организации.vcNsxt/create— создание сетевого шлюза NSX-T (включение AVI, выделение 4 Service Engine).vcOrg/modify— модификация организации (добавление 3 внешних IP-адресов).vcNsxt/modify— повторная модификация NSX-T (включение SNAT, привязка выделенногоipSpaceизvcOrg).Штурвал/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) — декомпозиция отложенных действий и привязок в отдельные управляемые ресурсы провайдера.
Структура ресурсов
- Базовые ресурсы жизненного цикла (Core Instances):
cloud_vc_org— создает и держит базу организации.cloud_vc_vdc— создает VDC внутри Org.cloud_vc_nsxt— создает NSX-T шлюз (AVI, 4 SE).
- Ресурсы отложенной конфигурации / модификаций (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.
- Целевой сервис:
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), код конкретных ресурсов не правится вручную, а генерируется:
- В схему генератора добавляются описания новых сущностей:
- Тип
actionилиsubresourceдля вызова эндпоинтов модификации. - Контракты входных/выходных атрибутов (
org_id,ip_count,ip_space_id,nsxt_id,enabled).
- Тип
- Кодогенератор генерирует стандартные 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.
- Вызывает соответствующий API-метод (
- 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. Альтернативные подходы
- Smart Provider (комбинированный Create):
- Если API позволяет вызывать шаги последовательно внутри одного HTTP-сеанса бэкенда, провайдер мог бы скрыть это внутри
Createресурсаcloud_shturval. - Минус: теряется гибкость и прозрачность статусов; сбой на промежуточном этапе оставляет "зависшие" ресурсы в облаке без записи в tfstate.
- Если API позволяет вызывать шаги последовательно внутри одного HTTP-сеанса бэкенда, провайдер мог бы скрыть это внутри
- Модули Terraform (Module Wrapper):
- Описанная выше структура ресурсов упаковывается в официальный Terraform-модуль
terraform-nubes-shturval, скрывая сложность связей от конечного пользователя и предоставляя простой интерфейс ввода параметров.
- Описанная выше структура ресурсов упаковывается в официальный Terraform-модуль