Files
tf_provider/docs/curated/pipeline/vdc_edge_ip_snat.md
T

6.5 KiB
Raw Blame History

Пайплайн: vDC → Edge → внешние IP → SNAT

Проверено на dev-стенде 2026-09-24 (провайдер 2.0.20): один apply собирает всю цепочку, повторный plan не показывает изменений, destroy проходит в обратном порядке.

Что делает пайплайн

Собирает сетевую основу под нагрузку: виртуальный датацентр, периметровый шлюз, внешние IP на организации и SNAT на шлюзе — без ручных операций в ЛК после создания организации.

Кластер Штурвал в этот пайплайн не входит — он разворачивается очень долго, это отдельный шаг.

Что вне Terraform (создаётся один раз вручную)

Организация в Cloud Director — одна на ресурсный realm, создать вторую нельзя. В конфиге она адресуется по UUID (org_uid), а её внешние IP выделяются уже Terraform-ресурсом.

Порядок и почему он такой

# Ресурс Что создаёт
1 nubes_vc_vdc виртуальный датацентр
2 nubes_vc_nsxt сетевой шлюз периметра (Edge), ALB/AVI
3 nubes_vc_org_ip_allocation внешние IP на организации (vIPConfigure)
4 nubes_vc_nsxt_snat SNAT на шлюзе (ipSpaceName)

Порядок обязателен: шаги 3 и 4 — операции modify, а платформа строит список доступных ipSpace из состояния job.vcd.networkProvider / job.vcd.providerGateway, то есть требует уже созданные vDC и Edge. В инструкции к операции это записано прямо: «предварительно необходимо создать Виртуальный датацентр (VDC), потом Сетевой шлюз периметра (Edge Gateway)». Если открыть modify на организации без vDC/Edge, список значений падает с ошибкой Can't cast Complex Object Type Struct to String.

Пример конфигурации

resource "nubes_vc_vdc" "vdc" {
  resource_name    = "fullpipe-vdc"
  organization_uid = var.organization   # имя или UUID существующей организации
  network_provider = "snb1"             # из ЛК
  provider_vdc     = "Intel Broadwell 2.4"
  storage_config   = jsonencode([{ name = "SATA", size = "200" }])
  suspend_on_destroy = true
}

resource "nubes_vc_nsxt" "edge" {
  resource_name = "fullpipe-edge"
  vdc_type      = "vdc"
  vdc_uid       = nubes_vc_vdc.vdc.id    # Edge создаётся только после vDC

  need_enable_avi        = true
  virtual_services_count = 3             # Штурвалу нужно ≥ 3
  routed_net_configuration = {
    ip_addr_pool = "10.10.102.0/24"
    main_dns     = "81.22.46.22"
    second_dns   = "185.247.187.77"
  }
}

# Внешние IP на организации — только после создания Edge
resource "nubes_vc_org_ip_allocation" "org_ip" {
  org_uid = var.org_uid                  # UUID организации

  vip_configure = jsonencode([
    { name = "internet-ipv4-v1", count = "3" }
  ])

  depends_on = [nubes_vc_nsxt.edge]
}

# SNAT на шлюзе этим ipSpace
resource "nubes_vc_nsxt_snat" "snat" {
  nsxt_uid      = nubes_vc_nsxt.edge.id
  ip_space_name = "internet-ipv4-v1"

  depends_on = [nubes_vc_org_ip_allocation.org_ip]
}

Порядок ключей в vip_configure и его форматирование значения не имеют — сравнение смысловое.

Готовые файлы примеров

Комплект .tf-файлов (vDC, Edge, аллокация IP, SNAT) лежит в отдельном репозитории примеров:

https://gitea.services.ngcloud.ru/Nail/tf_examples

  • каталог modify_resources/ — ресурсы-модификаторы (аллокация IP на организации + SNAT);
  • terraform.tfvars.example — шаблон переменных (реальный terraform.tfvars с токеном нигде не публикуется).

Клонирование целиком:

git clone https://gitea.services.ngcloud.ru/Nail/tf_examples.git

Значения, которые берутся из ЛК

Параметр Где смотреть
organization_uid / org_uid карточка услуги «Организация в Cloud Director»
network_provider, provider_vdc страница vDC
storage_config (имена политик) дисковые политики ресурсного пула (SATA, SSD)
ip_space_name список ipSpace организации (доступен после создания vDC и Edge)

Удаление

terraform destroy идёт в обратном порядке и сам приводит систему в исходное состояние:

# Ресурс Обратная операция
1 nubes_vc_nsxt_snat modify с ipSpaceName = "no-needed" (SNAT выключается)
2 nubes_vc_org_ip_allocation modify с count = "0" (квота IP обнуляется)
3 nubes_vc_nsxt удаление шлюза
4 nubes_vc_vdc удаление vDC

Организацию удаление не затрагивает. Если снимать SNAT или квоту не нужно — у ресурсов есть keep_on_destroy = true.

Что подтверждено живым прогоном (dev, 2026-09-24)

  • вся цепочка поднимается одним apply;
  • повторный plan не требует изменений;
  • после apply в API: у организации vIPConfigure: [{"name":"internet-ipv4-v1","count":"3"}], у шлюза ipSpaceName: "internet-ipv4-v1", при этом needEnableAVI и virtualServicesCount не затираются (SNAT-модификация отправляет только своё поле);
  • destroy выключает SNAT и обнуляет квоту, орг остаётся живой.