Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc837e8e1a | ||
|
|
223b0ccdca | ||
|
|
ea725bd8b9 | ||
|
|
48009583a6 | ||
|
|
e72eb75d10 | ||
|
|
8d25de9e79 | ||
|
|
f8d64948c8 | ||
|
|
e20c22e0cb |
@@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
variable "shturval_resource_name" {
|
variable "shturval_resource_name" {
|
||||||
type = string
|
type = string
|
||||||
default = "shturval-dev"
|
default = "shturval-dev1"
|
||||||
description = "Имя услуги «Kubernetes кластер Штурвал» в ЛК"
|
description = "Имя услуги «Kubernetes кластер Штурвал» в ЛК"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "shturval_cluster_name" {
|
variable "shturval_cluster_name" {
|
||||||
type = string
|
type = string
|
||||||
default = "shturval-dev-00"
|
default = "shturval-dev-01"
|
||||||
description = "Имя кластера внутри Штурвала"
|
description = "Имя кластера внутри Штурвала"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
api_token = "ВАШ_ТОКЕН_ИЗ_ЛК"
|
api_token = "ВАШ_ТОКЕН_ИЗ_ЛК"
|
||||||
|
|
||||||
# Имя или UUID организации:
|
# Имя или UUID организации:
|
||||||
organization = "kontora"
|
organization = "kontra"
|
||||||
|
|
||||||
vdc_resource_name = "fullpipe-vdc"
|
vdc_resource_name = "fullpipe-vdc"
|
||||||
vdc_network_provider = "snb1"
|
vdc_network_provider = "snb1"
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# 2026-09-25 — Штурвал в примере `fullpipe_chain` + страница документации
|
||||||
|
|
||||||
|
## Что сделано
|
||||||
|
|
||||||
|
Примеры (`tf_examples`, отдельный репозиторий `https://gitea.services.ngcloud.ru/Nail/tf_examples.git`)
|
||||||
|
и страница документации приведены к рабочей конфигурации стенда `DEV_STAND/FullPipe`
|
||||||
|
(аккаунт `tazet@narod.ru`) — теперь цепочка полная: **vDC → Edge → внешние IP → SNAT → Штурвал**.
|
||||||
|
|
||||||
|
| Файл | Изменение |
|
||||||
|
|---|---|
|
||||||
|
| `tf_examples/fullpipe_chain/shturval.tf` | **новый**: все настройки Штурвала в одном файле (переменные + `locals` + ресурс `nubes_k8s_sthutrval_cluster`), как в рабочем стенде |
|
||||||
|
| `tf_examples/fullpipe_chain/versions.tf` | провайдер `2.0.21` → `2.0.23` (последняя dev) |
|
||||||
|
| `tf_examples/fullpipe_chain/edge.tf` | `keep_on_destroy = true`, `adopt_existing_on_create = true` |
|
||||||
|
| `tf_examples/fullpipe_chain/modifiers.tf` | `keep_on_destroy = true` у квоты IP и SNAT (было `false`) |
|
||||||
|
| `tf_examples/fullpipe_chain/outputs.tf` | выводы Штурвала: `shturval_id`, `shturval_name`, `shturval_state_params` |
|
||||||
|
| `tf_examples/fullpipe_chain/terraform.tfvars.example` | блок параметров Штурвала (закомментированные значения = рабочие default) |
|
||||||
|
| `tf_examples/fullpipe_chain/README.md`, `tf_examples/README.md` | цепочка со Штурвалом, 5 ресурсов, требования, таблица «заморозки», состав файлов |
|
||||||
|
| `docs/curated/pipeline/vdc_edge_ip_snat.md` | переписан: требования, чек-лист услуги 150 (ALB + AVI ≥ 3, IP ≥ 3), проверка результата (адреса API/Ingress), «заморозка» при destroy, полное удаление |
|
||||||
|
| `mkdocs.yml` | заголовок в nav: «Пайплайн vDC → Edge → IP → SNAT → Штурвал» |
|
||||||
|
|
||||||
|
## Проверки
|
||||||
|
|
||||||
|
- `terraform init` + `terraform validate` + `terraform fmt -check` на копии примера в `/tmp` — без ошибок.
|
||||||
|
- `terraform plan` (копия в `/tmp`, организация `kontra`, токен `secrets/dev.token`) — `5 to add, 0 change, 0 destroy`, ошибок нет.
|
||||||
|
- Копия для проверки делалась в `/tmp`, **не** в `tf_examples/`: там нет `.gitignore` для `.terraform/`, и служебные файлы уехали бы в публичный репозиторий.
|
||||||
|
|
||||||
|
## Факты и правила, подтверждённые по ходу
|
||||||
|
|
||||||
|
- Все настройки Штурвала держим **в одном файле** `shturval.tf` (переменные + ресурс): чтобы выключить Штурвал — удалить файл.
|
||||||
|
- Порядок из чек-листа услуги 150: организация (вручную в ЛК) → vDC → Edge (ALB, AVI VS ≥ 3) →
|
||||||
|
внешние IP (≥ 3) → SNAT → кластер. Минимум ноды: 1 + 1 по 4 vCPU / 8 ГБ / 50 ГБ.
|
||||||
|
- `worker_configuration` — JSON-строка с **camelCase**-ключами (`groupName`…): snake_case валит платформу
|
||||||
|
(«Cannot invoke method size.split() on null object»).
|
||||||
|
- «Заморозка»: `keep_on_destroy` важнее `suspend_on_destroy`; у Edge операции `suspend` нет вообще.
|
||||||
|
- Публикация доков: `TOOLS/scripts/04_build_and_publish_docs.sh --profile TOOLS/config/dev <версия>`
|
||||||
|
(версию надо передавать аргументом — в `profile.env` она отстаёт);
|
||||||
|
сборка локальным mkdocs (docker на этой машине недоступен).
|
||||||
|
|
||||||
|
## Ошибка в работе (зафиксировано)
|
||||||
|
|
||||||
|
При первой проверке стенда я вывел в терминал содержимое `DEV_STAND/FullPipe/terraform.tfvars` —
|
||||||
|
файл содержит живой `api_token`. В git файл не попадает (`*.tfvars` в `.gitignore`), но токен оказался
|
||||||
|
в логе вывода. Правило: секреты из `.tfvars` не печатать, сравнивать по хешу/маскировать.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
resource "nubes_vc_nsxt" "edge" {
|
||||||
|
resource_name = var.nsxt_resource_name
|
||||||
|
|
||||||
|
# Тип родительской услуги: "vdc" (нужен vdc_uid) или "vdcGroup" (нужен vdc_group_uid)
|
||||||
|
vdc_type = var.nsxt_vdc_type
|
||||||
|
|
||||||
|
# refSvc-поле: принимает UUID или имя. Здесь берём UID созданного VDC,
|
||||||
|
# чтобы Edge гарантированно создавался после vDC.
|
||||||
|
vdc_uid = nubes_vc_vdc.vdc.id
|
||||||
|
|
||||||
|
need_enable_avi = var.nsxt_need_enable_avi
|
||||||
|
virtual_services_count = var.nsxt_virtual_services_count
|
||||||
|
|
||||||
|
# routed-сеть, которую разворачивает Edge (SingleNestedAttribute -> объект)
|
||||||
|
routed_net_configuration = {
|
||||||
|
ip_addr_pool = var.nsxt_ip_addr_pool
|
||||||
|
main_dns = var.nsxt_main_dns
|
||||||
|
second_dns = var.nsxt_second_dns
|
||||||
|
}
|
||||||
|
|
||||||
|
# «Заморозка»: destroy НЕ удаляет эдж (у платформы для эджа нет операции suspend),
|
||||||
|
# а только убирает его из состояния. Для полного удаления — keep_on_destroy = false.
|
||||||
|
keep_on_destroy = true
|
||||||
|
|
||||||
|
# Повторный apply усыновляет уже работающий эдж, а не падает с
|
||||||
|
# «РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)».
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Ресурсы-модификаторы (операции modify, которых нет в create-схеме ресурсов)
|
||||||
|
#
|
||||||
|
# Порядок строго такой:
|
||||||
|
# орга (создана вручную в ЛК)
|
||||||
|
# -> nubes_vc_vdc.vdc
|
||||||
|
# -> nubes_vc_nsxt.edge
|
||||||
|
# -> nubes_vc_org_ip_allocation (выделение внешних IP на орге)
|
||||||
|
# -> nubes_vc_nsxt_snat (SNAT на эдже этим ipSpace)
|
||||||
|
#
|
||||||
|
# Почему аллокация ПОСЛЕ эджа: платформа строит список ipSpace из состояния
|
||||||
|
# `job.vcd.networkProvider` / `job.vcd.providerGateway`, то есть требует уже
|
||||||
|
# созданный vDC и Edge. Иначе modify на орге падает
|
||||||
|
# («Can't cast Complex Object Type Struct to String»).
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 1. Внешние IP на организации (modify: vIPConfigure, массив перезаписывается целиком)
|
||||||
|
resource "nubes_vc_org_ip_allocation" "org_ip" {
|
||||||
|
organization = var.organization
|
||||||
|
|
||||||
|
vip_configure = jsonencode([
|
||||||
|
{
|
||||||
|
name = var.ip_space_name
|
||||||
|
count = var.ip_count
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# true = «заморозка»: destroy не трогает квоту внешних IP (кластер Штурвала держит
|
||||||
|
# адреса, опустить count ниже занятых платформа не даёт). Для полного удаления — false
|
||||||
|
# (и только после удаления кластера).
|
||||||
|
keep_on_destroy = true
|
||||||
|
|
||||||
|
depends_on = [nubes_vc_nsxt.edge]
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. SNAT на эдже (modify: ipSpaceName)
|
||||||
|
resource "nubes_vc_nsxt_snat" "snat" {
|
||||||
|
nsxt_uid = nubes_vc_nsxt.edge.id
|
||||||
|
ip_space_name = var.ip_space_name
|
||||||
|
|
||||||
|
# true = «заморозка»: destroy не выключает SNAT на эдже. Для полного удаления — false.
|
||||||
|
keep_on_destroy = true
|
||||||
|
|
||||||
|
# ipSpace должен быть уже выделен на организации
|
||||||
|
depends_on = [nubes_vc_org_ip_allocation.org_ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "allocated_org_ip" {
|
||||||
|
description = "Выделено внешних IP на организации"
|
||||||
|
value = {
|
||||||
|
organization = var.organization
|
||||||
|
ip_space_name = var.ip_space_name
|
||||||
|
ip_count = var.ip_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "snat_ip_space" {
|
||||||
|
description = "ipSpace, включённый как SNAT на эдже"
|
||||||
|
value = nubes_vc_nsxt_snat.snat.ip_space_name
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
output "vdc_id" {
|
||||||
|
description = "UID созданного VDC"
|
||||||
|
value = nubes_vc_vdc.vdc.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vdc_name" {
|
||||||
|
description = "Имя VDC"
|
||||||
|
value = nubes_vc_vdc.vdc.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vdc_state_params" {
|
||||||
|
description = "Параметры состояния VDC из API"
|
||||||
|
value = nubes_vc_vdc.vdc.state_params
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_id" {
|
||||||
|
description = "UID созданного Edge (vc_nsxt)"
|
||||||
|
value = nubes_vc_nsxt.edge.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_name" {
|
||||||
|
description = "Имя Edge (vc_nsxt)"
|
||||||
|
value = nubes_vc_nsxt.edge.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_state_params" {
|
||||||
|
description = "Параметры состояния Edge (vc_nsxt) из API"
|
||||||
|
value = nubes_vc_nsxt.edge.state_params
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
provider "nubes" {
|
||||||
|
api_token = var.api_token
|
||||||
|
api_endpoint = var.api_endpoint
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Kubernetes кластер Штурвал — сервис 150, ресурс nubes_k8s_sthutrval_cluster
|
||||||
|
# (НЕ 148 «Менеджмент Kubernetes кластер Штурвал» — это другой сервис)
|
||||||
|
#
|
||||||
|
# Всё, что относится к Штурвалу, лежит ТОЛЬКО в этом файле: переменные, их
|
||||||
|
# значения по умолчанию и сам ресурс. Чтобы выключить Штурвал — удалить файл
|
||||||
|
# или закомментировать ресурс.
|
||||||
|
#
|
||||||
|
# Порядок (чек-лист из инструкции на услугу в ЛК):
|
||||||
|
# 1) Организация в Cloud Director — создана вручную в ЛК
|
||||||
|
# 2) nubes_vc_vdc.vdc — есть
|
||||||
|
# 3) nubes_vc_nsxt.edge — есть, обязательно ALB + AVI VS >= 3
|
||||||
|
# 4) внешние адреса в организации — суммарно >= 3 (nubes_vc_org_ip_allocation)
|
||||||
|
# 5) SNAT на Edge — nubes_vc_nsxt_snat
|
||||||
|
# 6) Kubernetes кластер Штурвал — этот ресурс
|
||||||
|
#
|
||||||
|
# Минимальные требования к кластеру: мастер-нод >= 1, воркер-нод >= 1,
|
||||||
|
# 4 vCPU / 8 GB RAM / 50 GB диска на ноду.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# --- Переменные Штурвала ---
|
||||||
|
|
||||||
|
variable "shturval_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "shturval-dev"
|
||||||
|
description = "Имя услуги «Kubernetes кластер Штурвал» в ЛК"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_cluster_name" {
|
||||||
|
type = string
|
||||||
|
default = "shturval-dev-00"
|
||||||
|
description = "Имя кластера внутри Штурвала"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_app_version" {
|
||||||
|
type = string
|
||||||
|
default = "2.14.0"
|
||||||
|
description = "Версия Штурвала (значение по умолчанию платформы — 2.14.0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_cp_sizing_policy" {
|
||||||
|
type = string
|
||||||
|
default = "TKG 4CPU 8RAM"
|
||||||
|
description = "Политика размера control plane: 4 vCPU / 8 GB (минимум по инструкции). Должна существовать в ресурсной платформе vDC — список политик берётся из услуги «Виртуальный датацентр»"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_cp_sizing_disk" {
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = "Диск control plane, ГБ (минимум 50)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_cp_count" {
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = "Количество мастер-нод: 1, 3 или 5"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_worker_group_name" {
|
||||||
|
type = string
|
||||||
|
default = "workers-shturval-dev"
|
||||||
|
description = "Имя группы воркеров (уникальное в кластере; допустимы строчные латинские буквы, цифры и дефис)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_worker_sizing_policy" {
|
||||||
|
type = string
|
||||||
|
default = "TKG 4CPU 8RAM"
|
||||||
|
description = "Политика размера воркеров: 4 vCPU / 8 GB (минимум по инструкции)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_worker_sizing_disk" {
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = "Диск воркеров, ГБ (минимум 50)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "shturval_worker_count" {
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = "Количество воркер-нод (минимум 1)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Значения, которые собираются из переменных ---
|
||||||
|
|
||||||
|
locals {
|
||||||
|
# Группы воркеров передаются JSON-строкой ВНУТРЬ услуги как есть, поэтому ключи
|
||||||
|
# должны быть ровно такими, как в манифесте услуги 150: groupName, sizingPolicy,
|
||||||
|
# sizingDisk, count, autoscale, labelDeck.
|
||||||
|
# ВНИМАНИЕ: в сгенерированном примере провайдера (docs → Example) ключи показаны
|
||||||
|
# в snake_case — это ошибка генератора, платформа на них падает с
|
||||||
|
# «Cannot invoke method split() on null object» (не находит groupName → null).
|
||||||
|
shturval_worker_config = jsonencode([
|
||||||
|
{
|
||||||
|
groupName = var.shturval_worker_group_name
|
||||||
|
sizingPolicy = var.shturval_worker_sizing_policy
|
||||||
|
sizingDisk = var.shturval_worker_sizing_disk
|
||||||
|
count = var.shturval_worker_count
|
||||||
|
autoscale = false # автоскейл выключен
|
||||||
|
labelDeck = true # разрешить разворачивать услуги из ЛК на этих нодах
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Ресурс Штурвала ---
|
||||||
|
|
||||||
|
resource "nubes_k8s_sthutrval_cluster" "shturval" {
|
||||||
|
resource_name = var.shturval_resource_name
|
||||||
|
|
||||||
|
# Кластер Штурвала уже существует (инстанс «shturval-dev») и в проде не
|
||||||
|
# удаляется неделями, поэтому ресурс должен УСЫНОВИТЬ существующий инстанс,
|
||||||
|
# а не падать с «РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (SUSPEND)».
|
||||||
|
# Проверка/adopt выполняются в Create на apply (в plan будет «will be created»).
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
|
||||||
|
# «Заморозка»: destroy приостанавливает кластер (suspend), а не удаляет.
|
||||||
|
# Следующий apply усыновит его и разморозит (resume).
|
||||||
|
suspend_on_destroy = true
|
||||||
|
|
||||||
|
# Штурвал создаётся долго (десятки минут) — поднимаем таймаут ожидания,
|
||||||
|
# иначе провайдер сдаётся на дефолтных 600 с.
|
||||||
|
operation_timeout = "60m"
|
||||||
|
|
||||||
|
startup_configuration = {
|
||||||
|
# vDC и Edge из этого же конфига (обязательные поля)
|
||||||
|
vdc_uid = nubes_vc_vdc.vdc.id
|
||||||
|
nsxt_uid = nubes_vc_nsxt.edge.id
|
||||||
|
|
||||||
|
cluster_name = var.shturval_cluster_name
|
||||||
|
|
||||||
|
# Дополнительные возможности кластера (в ЛК — галочки при создании)
|
||||||
|
ex_logging = true # логи в Loki (без него логи услуг не видны в ЛК)
|
||||||
|
ex_monitoring = true # метрики в VictoriaMetrics (без него метрик в ЛК нет)
|
||||||
|
ex_local_csi = true
|
||||||
|
ex_vip = true
|
||||||
|
ex_update = true
|
||||||
|
ex_ingress = true
|
||||||
|
ex_named_csi = true
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster_configuration = {
|
||||||
|
app_version = var.shturval_app_version
|
||||||
|
}
|
||||||
|
|
||||||
|
control_plane_configuration = {
|
||||||
|
sizing_policy = var.shturval_cp_sizing_policy
|
||||||
|
sizing_disk = var.shturval_cp_sizing_disk
|
||||||
|
count = var.shturval_cp_count
|
||||||
|
}
|
||||||
|
|
||||||
|
worker_configuration = local.shturval_worker_config
|
||||||
|
|
||||||
|
access_configuration = {
|
||||||
|
need_external_address_api = true # внешний адрес для Kubernetes API (false недопустим)
|
||||||
|
access_ip_list_api = jsonencode([]) # пусто = доступ всем
|
||||||
|
need_external_address_ingress = true # внешний адрес для Ingress
|
||||||
|
access_ip_list_ingress = jsonencode([]) # пусто = доступ всем
|
||||||
|
}
|
||||||
|
|
||||||
|
# Кластер поднимается только после готовой сети: vDC -> Edge -> внешние IP -> SNAT
|
||||||
|
depends_on = [nubes_vc_nsxt_snat.snat]
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
api_token = "ВАШ_ТОКЕН_ИЗ_ЛК"
|
||||||
|
|
||||||
|
# Имя или UUID организации:
|
||||||
|
organization = "kontora"
|
||||||
|
|
||||||
|
vdc_resource_name = "fullpipe-vdc"
|
||||||
|
vdc_network_provider = "snb1"
|
||||||
|
vdc_provider_vdc = "Intel Broadwell 2.4"
|
||||||
|
vdc_cpu_allocated = 8
|
||||||
|
vdc_cpu_guaranteed = 0
|
||||||
|
vdc_mem_allocated = 32
|
||||||
|
|
||||||
|
vdc_storage_config = "[{\"name\":\"SATA\",\"size\":\"200\"}]"
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
variable "api_token" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "API-токен Nubes"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "api_endpoint" {
|
||||||
|
type = string
|
||||||
|
default = "https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc"
|
||||||
|
description = "API Gateway URL"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Имя (display_name, напр. "kontora") ИЛИ UUID организации из ЛК
|
||||||
|
variable "organization" {
|
||||||
|
type = string
|
||||||
|
description = "Имя или UUID организации (vc_org)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Модификаторы (IP на орге + SNAT на эдже) ---
|
||||||
|
|
||||||
|
variable "ip_space_name" {
|
||||||
|
type = string
|
||||||
|
description = "Имя ipSpace, доступное организации (смотреть в ЛК, напр. internet-ipv4-v1)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ip_count" {
|
||||||
|
type = string
|
||||||
|
default = "3"
|
||||||
|
description = "Сколько внешних IP выделить на организации (count — строка)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-vdc"
|
||||||
|
description = "Имя VDC"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_network_provider" {
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
description = "Сетевой провайдер. Заполнить значением из текущей страницы ЛК"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_provider_vdc" {
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
description = "Provider VDC. Заполнить значением из текущей страницы ЛК"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_cpu_allocated" {
|
||||||
|
type = number
|
||||||
|
default = 8
|
||||||
|
description = "vCPU (шт.)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_cpu_guaranteed" {
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = "Резервирование vCPU (%, допустимо: 0, 50, 80)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_mem_allocated" {
|
||||||
|
type = number
|
||||||
|
default = 32
|
||||||
|
description = "RAM (GB)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_storage_config" {
|
||||||
|
type = string
|
||||||
|
default = "[{\"name\":\"SATA\",\"size\":\"200\"}]"
|
||||||
|
description = "Дисковое хранилище (JSON-массив, size в GB). Имя политики должно существовать в ресурсном пуле (например, SATA, SSD)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- vc_nsxt (Сетевой шлюз периметра / Edge) ---
|
||||||
|
|
||||||
|
variable "nsxt_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-edge"
|
||||||
|
description = "Имя Edge (vc_nsxt)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_vdc_type" {
|
||||||
|
type = string
|
||||||
|
default = "vdc"
|
||||||
|
description = "Тип родительской услуги: vdc или vdcGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_need_enable_avi" {
|
||||||
|
type = bool
|
||||||
|
default = true
|
||||||
|
description = "Включить AVI Load Balancer (ALB)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_virtual_services_count" {
|
||||||
|
type = number
|
||||||
|
default = 3
|
||||||
|
description = "Кол-во виртуальных сервисов на AVI (1..4; Штурвал: ≥ 3)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_ip_addr_pool" {
|
||||||
|
type = string
|
||||||
|
default = "10.10.102.0/24"
|
||||||
|
description = "Адресный пул routed-сети (маска /24 обязательна)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_main_dns" {
|
||||||
|
type = string
|
||||||
|
default = "81.22.46.22"
|
||||||
|
description = "Основной DNS"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_second_dns" {
|
||||||
|
type = string
|
||||||
|
default = "185.247.187.77"
|
||||||
|
description = "Второй DNS"
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
resource "nubes_vc_vdc" "vdc" {
|
||||||
|
resource_name = var.vdc_resource_name
|
||||||
|
|
||||||
|
# Организация: имя из ЛК ("kontora") или точный UUID
|
||||||
|
organization_uid = var.organization
|
||||||
|
|
||||||
|
network_provider = var.vdc_network_provider
|
||||||
|
provider_vdc = var.vdc_provider_vdc
|
||||||
|
|
||||||
|
cpu_allocated = var.vdc_cpu_allocated
|
||||||
|
cpu_guaranteed = var.vdc_cpu_guaranteed
|
||||||
|
mem_allocated = var.vdc_mem_allocated
|
||||||
|
|
||||||
|
# JSON-массив дисковых политик (size в GB)
|
||||||
|
storage_config = var.vdc_storage_config
|
||||||
|
|
||||||
|
suspend_on_destroy = true
|
||||||
|
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.5.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
nubes = {
|
||||||
|
source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes"
|
||||||
|
version = "2.0.23"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# vDC → Edge → внешние IP → SNAT
|
||||||
|
|
||||||
|
Пример поднимает сетевую основу в Nubes:
|
||||||
|
|
||||||
|
- виртуальный датацентр (vDC);
|
||||||
|
- сетевой шлюз периметра (Edge);
|
||||||
|
- внешние IP на организации;
|
||||||
|
- SNAT на шлюзе.
|
||||||
|
|
||||||
|
Кластер Штурвал сюда **не входит** — он разворачивается долго, отдельным шагом.
|
||||||
|
Организацию создайте заранее в ЛК: Terraform её не создаёт и не удаляет.
|
||||||
|
|
||||||
|
**Перед началом:** нужен установленный Terraform 1.5 или новее. Провайдер скачается сам
|
||||||
|
при `terraform init` — отдельно ставить ничего не нужно.
|
||||||
|
|
||||||
|
## 1. Скачайте пример
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.services.ngcloud.ru/Nail/tf_examples.git
|
||||||
|
cd tf_examples/fullpipe_chain
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Возьмите значения в ЛК
|
||||||
|
|
||||||
|
| Значение | Где взять | Пример |
|
||||||
|
|---|---|---|
|
||||||
|
| `api_token` | ЛК → Профиль → Токены → «Технический» | `eyJhbGciOi...` |
|
||||||
|
| `organization` | ЛК → услуга «Организация в Cloud Director» → название услуги | `organ` |
|
||||||
|
| `vdc_network_provider` | ЛК → создание vDC → «Сетевой провайдер» | `snb1` |
|
||||||
|
| `vdc_provider_vdc` | ЛК → создание vDC → «Provider VDC» | `Intel Broadwell 2.4` |
|
||||||
|
| `vdc_storage_config` | ЛК → создание vDC → доступные дисковые политики | `SATA` |
|
||||||
|
| `ip_space_name` | ЛК → карточка организации → внешние IP | `internet-ipv4-v1` |
|
||||||
|
|
||||||
|
Остальные значения уже подставлены в `terraform.tfvars.example` — меняйте, если нужно.
|
||||||
|
|
||||||
|
## 3. Заполните terraform.tfvars
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp terraform.tfvars.example terraform.tfvars
|
||||||
|
nano terraform.tfvars # подставьте значения из шага 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Полный список параметров — в `variables.tf`, у каждой переменной есть описание.
|
||||||
|
|
||||||
|
## 4. Выполните команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform init # один раз — скачает провайдер
|
||||||
|
terraform plan # покажет, что будет создано (4 ресурса), ничего не меняет
|
||||||
|
terraform apply # создаст (подтвердить: yes)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Проверьте результат
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform output # UUID и имена созданных услуг
|
||||||
|
```
|
||||||
|
|
||||||
|
И в ЛК: появились vDC и Edge, на организации выделены внешние IP, на шлюзе включён SNAT.
|
||||||
|
Повторный `terraform plan` должен показать `No changes`.
|
||||||
|
|
||||||
|
## 6. Удаление
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform destroy
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядок обратный: SNAT выключается, квота внешних IP обнуляется, затем удаляется шлюз,
|
||||||
|
а vDC приостанавливается (данные сохраняются).
|
||||||
|
**Организация не удаляется.**
|
||||||
|
|
||||||
|
## Состав файлов
|
||||||
|
|
||||||
|
| Файл | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `versions.tf` | версия Terraform и провайдера Nubes |
|
||||||
|
| `provider.tf` | подключение к API (токен, адрес) |
|
||||||
|
| `variables.tf` | все параметры с описанием |
|
||||||
|
| `vdc.tf` | виртуальный датацентр |
|
||||||
|
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
||||||
|
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
||||||
|
| `outputs.tf` | UUID и имена созданных услуг |
|
||||||
|
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
||||||
|
|
||||||
|
`terraform.tfvars` с токеном никому не передавайте и не коммитьте в git.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Сетевой шлюз периметра (Edge) — создаётся внутри vDC, объявленного в vdc.tf.
|
||||||
|
resource "nubes_vc_nsxt" "edge" {
|
||||||
|
# имя услуги в ЛК (любое, удобное вам)
|
||||||
|
resource_name = var.nsxt_resource_name
|
||||||
|
|
||||||
|
# родительская услуга: vdc (нужен vdc_uid) или vdcGroup
|
||||||
|
vdc_type = var.nsxt_vdc_type
|
||||||
|
|
||||||
|
# ссылка на vDC: сначала создаётся vDC, потом шлюз
|
||||||
|
vdc_uid = nubes_vc_vdc.vdc.id
|
||||||
|
|
||||||
|
# балансировщик (ALB): включён; виртуальных сервисов 1..4,
|
||||||
|
# для кластера Штурвал нужно не меньше 3
|
||||||
|
need_enable_avi = var.nsxt_need_enable_avi
|
||||||
|
virtual_services_count = var.nsxt_virtual_services_count
|
||||||
|
|
||||||
|
# сеть шлюза: пул адресов (маска /24 обязательна) и DNS для машин
|
||||||
|
routed_net_configuration = {
|
||||||
|
ip_addr_pool = var.nsxt_ip_addr_pool
|
||||||
|
main_dns = var.nsxt_main_dns
|
||||||
|
second_dns = var.nsxt_second_dns
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Ресурсы, которые выполняют операции modify над уже созданными услугами.
|
||||||
|
#
|
||||||
|
# Порядок строго такой:
|
||||||
|
# организация (создаётся заранее в ЛК)
|
||||||
|
# -> nubes_vc_vdc.vdc
|
||||||
|
# -> nubes_vc_nsxt.edge
|
||||||
|
# -> nubes_vc_org_ip_allocation (внешние IP на организации)
|
||||||
|
# -> nubes_vc_nsxt_snat (SNAT на шлюзе этим ipSpace)
|
||||||
|
#
|
||||||
|
# Аллокация IP идёт ПОСЛЕ шлюза: платформа строит список доступных ipSpace
|
||||||
|
# только когда vDC и Edge уже созданы. Если поменять порядок — modify упадёт
|
||||||
|
# с ошибкой «Can't cast Complex Object Type Struct to String».
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# 1. Внешние IP на организации.
|
||||||
|
resource "nubes_vc_org_ip_allocation" "org_ip" {
|
||||||
|
# та же организация, что у vDC: название услуги из ЛК или её UUID
|
||||||
|
organization = var.organization
|
||||||
|
|
||||||
|
# сколько IP выделить: name — имя ipSpace, count — количество (строкой).
|
||||||
|
# массив передаётся целиком, поэтому старые значения перезаписываются
|
||||||
|
vip_configure = jsonencode([
|
||||||
|
{
|
||||||
|
name = var.ip_space_name
|
||||||
|
count = var.ip_count
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# при destroy: false — квота обнуляется (count=0); true — оставить как есть
|
||||||
|
keep_on_destroy = false
|
||||||
|
|
||||||
|
depends_on = [nubes_vc_nsxt.edge]
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. SNAT на шлюзе: внешние адреса для машин.
|
||||||
|
resource "nubes_vc_nsxt_snat" "snat" {
|
||||||
|
# UUID шлюза, созданного выше
|
||||||
|
nsxt_uid = nubes_vc_nsxt.edge.id
|
||||||
|
ip_space_name = var.ip_space_name
|
||||||
|
|
||||||
|
# при destroy: false — SNAT выключается (no-needed); true — оставить как есть
|
||||||
|
keep_on_destroy = false
|
||||||
|
|
||||||
|
# ipSpace должен быть уже выделен на организации
|
||||||
|
depends_on = [nubes_vc_org_ip_allocation.org_ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "allocated_org_ip" {
|
||||||
|
description = "Внешние IP, выделенные на организации"
|
||||||
|
value = {
|
||||||
|
organization = var.organization
|
||||||
|
ip_space_name = var.ip_space_name
|
||||||
|
ip_count = var.ip_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "snat_ip_space" {
|
||||||
|
description = "ipSpace, включённый как SNAT на шлюзе"
|
||||||
|
value = nubes_vc_nsxt_snat.snat.ip_space_name
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Значения, нужные для дальнейшей работы (например, чтобы привязать к шлюзу
|
||||||
|
# кластер Штурвал или другие услуги).
|
||||||
|
|
||||||
|
output "vdc_id" {
|
||||||
|
description = "UUID созданного vDC"
|
||||||
|
value = nubes_vc_vdc.vdc.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vdc_name" {
|
||||||
|
description = "Имя vDC"
|
||||||
|
value = nubes_vc_vdc.vdc.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_id" {
|
||||||
|
description = "UUID созданного Edge (сетевого шлюза периметра)"
|
||||||
|
value = nubes_vc_nsxt.edge.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_name" {
|
||||||
|
description = "Имя Edge"
|
||||||
|
value = nubes_vc_nsxt.edge.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vdc_state_params" {
|
||||||
|
description = "Параметры vDC из API (что реально создалось)"
|
||||||
|
value = nubes_vc_vdc.vdc.state_params
|
||||||
|
}
|
||||||
|
|
||||||
|
output "nsxt_state_params" {
|
||||||
|
description = "Параметры Edge из API (что реально создалось)"
|
||||||
|
value = nubes_vc_nsxt.edge.state_params
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Подключение к API Nubes.
|
||||||
|
# Токен и адрес API берутся из terraform.tfvars (переменные api_token, api_endpoint).
|
||||||
|
provider "nubes" {
|
||||||
|
api_token = var.api_token
|
||||||
|
api_endpoint = var.api_endpoint
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Шаблон значений для fullpipe_chain.
|
||||||
|
#
|
||||||
|
# 1. Скопируйте файл: cp terraform.tfvars.example terraform.tfvars
|
||||||
|
# 2. Заполните значения ниже (откуда брать — в комментариях и в README.md).
|
||||||
|
# 3. terraform.tfvars НЕ публикуйте и не коммитьте: в нём токен доступа.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# ЛК → Профиль → Токены → «Технический»
|
||||||
|
api_token = "eyJhbGciOi..."
|
||||||
|
|
||||||
|
# Название услуги «Организация в Cloud Director» в ЛК (например: organ).
|
||||||
|
# Организацию создайте заранее в ЛК — Terraform её не создаёт и не удаляет.
|
||||||
|
organization = "organ"
|
||||||
|
|
||||||
|
# Имя ipSpace для внешнего IP. Смотреть в ЛК в карточке организации.
|
||||||
|
ip_space_name = "internet-ipv4-v1"
|
||||||
|
# Сколько внешних IP выделить (строкой).
|
||||||
|
ip_count = "3"
|
||||||
|
|
||||||
|
# --- vDC (виртуальный датацентр) ---
|
||||||
|
|
||||||
|
# Имя vDC в ЛК — любое.
|
||||||
|
vdc_resource_name = "fullpipe-vdc"
|
||||||
|
# ЛК → создание vDC → «Сетевой провайдер»
|
||||||
|
vdc_network_provider = "snb1"
|
||||||
|
# ЛК → создание vDC → «Provider VDC»
|
||||||
|
vdc_provider_vdc = "Intel Broadwell 2.4"
|
||||||
|
# vCPU, шт.
|
||||||
|
vdc_cpu_allocated = 8
|
||||||
|
# Резервирование vCPU, %: допустимы 0, 50 или 80
|
||||||
|
vdc_cpu_guaranteed = 0
|
||||||
|
# RAM, ГБ
|
||||||
|
vdc_mem_allocated = 32
|
||||||
|
# Дисковая политика: JSON-массив, name — имя политики из ЛК, size — размер в ГБ.
|
||||||
|
# Пример: политика SATA, 200 ГБ.
|
||||||
|
vdc_storage_config = "[{\"name\":\"SATA\",\"size\":\"200\"}]"
|
||||||
|
|
||||||
|
# --- Edge (сетевой шлюз периметра) ---
|
||||||
|
|
||||||
|
# Имя Edge в ЛК — любое.
|
||||||
|
nsxt_resource_name = "fullpipe-edge"
|
||||||
|
# Родительская услуга: vdc или vdcGroup.
|
||||||
|
nsxt_vdc_type = "vdc"
|
||||||
|
# Балансировщик AVI (ALB).
|
||||||
|
nsxt_need_enable_avi = true
|
||||||
|
# Виртуальных сервисов AVI: 1..4. Для кластера Штурвал нужно не меньше 3.
|
||||||
|
nsxt_virtual_services_count = 3
|
||||||
|
# Адресный пул routed-сети шлюза. Маска /24 обязательна.
|
||||||
|
nsxt_ip_addr_pool = "10.10.102.0/24"
|
||||||
|
# DNS для машин за шлюзом.
|
||||||
|
nsxt_main_dns = "81.22.46.22"
|
||||||
|
nsxt_second_dns = "185.247.187.77"
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Переменные. Все значения задаются в terraform.tfvars.
|
||||||
|
# Шаблон файла: terraform.tfvars.example (скопируйте в terraform.tfvars).
|
||||||
|
# Где взять каждое значение — в описании переменной и в README.md.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
variable "api_token" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "Токен API. ЛК → Профиль → Токены → «Технический». Никому не передавайте: токен даёт полный доступ к услугам."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "api_endpoint" {
|
||||||
|
type = string
|
||||||
|
default = "https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc"
|
||||||
|
description = "Адрес API. Менять не нужно."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Организация ---
|
||||||
|
|
||||||
|
variable "organization" {
|
||||||
|
type = string
|
||||||
|
description = "Название услуги «Организация в Cloud Director» в ЛК (например: organ). Можно указать и её UUID. Организация создаётся заранее в ЛК — Terraform её не создаёт."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ip_space_name" {
|
||||||
|
type = string
|
||||||
|
description = "Имя ipSpace для внешнего IP. Смотреть в ЛК в карточке организации (например: internet-ipv4-v1)."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ip_count" {
|
||||||
|
type = string
|
||||||
|
default = "3"
|
||||||
|
description = "Сколько внешних IP выделить на организации. Строкой — так его отдаёт платформа."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- vDC (виртуальный датацентр) ---
|
||||||
|
|
||||||
|
variable "vdc_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-vdc"
|
||||||
|
description = "Имя vDC в ЛК. Любое, удобное вам."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_network_provider" {
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
description = "Сетевой провайдер vDC. Взять в ЛК на странице создания vDC (например: snb1)."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_provider_vdc" {
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
description = "Provider VDC. Взять в ЛК на странице создания vDC (например: Intel Broadwell 2.4)."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_cpu_allocated" {
|
||||||
|
type = number
|
||||||
|
default = 8
|
||||||
|
description = "vCPU, шт."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_cpu_guaranteed" {
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = "Резервирование vCPU, %. Допустимы только 0, 50 или 80."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_mem_allocated" {
|
||||||
|
type = number
|
||||||
|
default = 32
|
||||||
|
description = "RAM, ГБ."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vdc_storage_config" {
|
||||||
|
type = string
|
||||||
|
default = "[{\"name\":\"SATA\",\"size\":\"200\"}]"
|
||||||
|
description = "Дисковая политика: JSON-массив, name — имя политики из ЛК, size — размер в ГБ (строкой). Имя политики должно существовать в ресурсном пуле (например: SATA, SSD)."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Edge (сетевой шлюз периметра, vc_nsxt) ---
|
||||||
|
|
||||||
|
variable "nsxt_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-edge"
|
||||||
|
description = "Имя Edge в ЛК. Любое, удобное вам."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_vdc_type" {
|
||||||
|
type = string
|
||||||
|
default = "vdc"
|
||||||
|
description = "Тип родительской услуги: vdc (нужен vdc_uid) или vdcGroup."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_need_enable_avi" {
|
||||||
|
type = bool
|
||||||
|
default = true
|
||||||
|
description = "Включить балансировщик AVI (ALB)."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_virtual_services_count" {
|
||||||
|
type = number
|
||||||
|
default = 3
|
||||||
|
description = "Количество виртуальных сервисов на AVI: 1..4. Для кластера Штурвал нужно не меньше 3."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_ip_addr_pool" {
|
||||||
|
type = string
|
||||||
|
default = "10.10.102.0/24"
|
||||||
|
description = "Адресный пул routed-сети шлюза. Маска /24 обязательна."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_main_dns" {
|
||||||
|
type = string
|
||||||
|
default = "81.22.46.22"
|
||||||
|
description = "Основной DNS для машин за шлюзом."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "nsxt_second_dns" {
|
||||||
|
type = string
|
||||||
|
default = "185.247.187.77"
|
||||||
|
description = "Второй DNS для машин за шлюзом."
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Виртуальный датацентр (vDC) — создаётся внутри организации из terraform.tfvars.
|
||||||
|
resource "nubes_vc_vdc" "vdc" {
|
||||||
|
# имя услуги в ЛК (любое, удобное вам)
|
||||||
|
resource_name = var.vdc_resource_name
|
||||||
|
|
||||||
|
# организация, к которой привязан vDC: название услуги из ЛК или её UUID
|
||||||
|
organization_uid = var.organization
|
||||||
|
|
||||||
|
# значения из ЛК со страницы создания vDC
|
||||||
|
network_provider = var.vdc_network_provider
|
||||||
|
provider_vdc = var.vdc_provider_vdc
|
||||||
|
|
||||||
|
# квоты: vCPU (шт.), резервирование vCPU (%), RAM (ГБ)
|
||||||
|
# для cpu_guaranteed допустимы только 0, 50 или 80
|
||||||
|
cpu_allocated = var.vdc_cpu_allocated
|
||||||
|
cpu_guaranteed = var.vdc_cpu_guaranteed
|
||||||
|
mem_allocated = var.vdc_mem_allocated
|
||||||
|
|
||||||
|
# дисковые политики: JSON-массив, name — имя политики из ЛК, size — размер в ГБ
|
||||||
|
storage_config = var.vdc_storage_config
|
||||||
|
|
||||||
|
# при destroy не удалять vDC, а приостановить (данные сохраняются)
|
||||||
|
suspend_on_destroy = true
|
||||||
|
|
||||||
|
# если услуга с таким именем уже есть — подключиться к ней, а не падать с ошибкой
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Версия Terraform и провайдера Nubes.
|
||||||
|
# Провайдер скачается сам при `terraform init` — вручную ставить ничего не нужно.
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 1.5.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
nubes = {
|
||||||
|
source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes"
|
||||||
|
version = "2.0.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# Как развернуть vDC, Edge, внешние IP и SNAT
|
||||||
|
|
||||||
|
Пошаговая инструкция. Готовые файлы примера — в репозитории `tf_examples`, папка `fullpipe_chain`.
|
||||||
|
|
||||||
|
Что получится в итоге:
|
||||||
|
|
||||||
|
- виртуальный датацентр (vDC);
|
||||||
|
- сетевой шлюз периметра (Edge);
|
||||||
|
- внешние IP на организации;
|
||||||
|
- SNAT на шлюзе.
|
||||||
|
|
||||||
|
Кластер Штурвал в эту инструкцию не входит — он разворачивается долго, отдельным шагом.
|
||||||
|
|
||||||
|
**Организацию создайте заранее в ЛК** — Terraform её не создаёт и не удаляет.
|
||||||
|
|
||||||
|
## 1. Скачайте пример
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.services.ngcloud.ru/Nail/tf_examples.git
|
||||||
|
cd tf_examples/fullpipe_chain
|
||||||
|
```
|
||||||
|
|
||||||
|
Понадобится Terraform 1.5 или новее. Провайдер скачается сам при `terraform init`.
|
||||||
|
|
||||||
|
## 2. Возьмите значения в ЛК
|
||||||
|
|
||||||
|
| Значение | Где взять | Пример |
|
||||||
|
|---|---|---|
|
||||||
|
| `api_token` | ЛК → Профиль → Токены → «Технический» | `eyJhbGciOi...` |
|
||||||
|
| `organization` | ЛК → услуга «Организация в Cloud Director» → название услуги | `organ` |
|
||||||
|
| `vdc_network_provider` | ЛК → создание vDC → «Сетевой провайдер» | `snb1` |
|
||||||
|
| `vdc_provider_vdc` | ЛК → создание vDC → «Provider VDC» | `Intel Broadwell 2.4` |
|
||||||
|
| `vdc_storage_config` | ЛК → создание vDC → доступные дисковые политики | `SATA` |
|
||||||
|
| `ip_space_name` | ЛК → карточка организации → внешние IP | `internet-ipv4-v1` |
|
||||||
|
|
||||||
|
## 3. Заполните значения
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp terraform.tfvars.example terraform.tfvars
|
||||||
|
nano terraform.tfvars
|
||||||
|
```
|
||||||
|
|
||||||
|
Файл `terraform.tfvars` выглядит так:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
# Токен из ЛК
|
||||||
|
api_token = "eyJhbGciOi..."
|
||||||
|
|
||||||
|
# Организация из ЛК (создана заранее)
|
||||||
|
organization = "organ"
|
||||||
|
|
||||||
|
# Внешние IP
|
||||||
|
ip_space_name = "internet-ipv4-v1"
|
||||||
|
ip_count = "3"
|
||||||
|
|
||||||
|
# vDC
|
||||||
|
vdc_resource_name = "fullpipe-vdc" # имя услуги в ЛК, любое
|
||||||
|
vdc_network_provider = "snb1" # ЛК → создание vDC → «Сетевой провайдер»
|
||||||
|
vdc_provider_vdc = "Intel Broadwell 2.4" # ЛК → создание vDC → «Provider VDC»
|
||||||
|
vdc_cpu_allocated = 8 # vCPU, шт.
|
||||||
|
vdc_cpu_guaranteed = 0 # резервирование vCPU, %: 0, 50 или 80
|
||||||
|
vdc_mem_allocated = 32 # RAM, ГБ
|
||||||
|
vdc_storage_config = "[{\"name\":\"SATA\",\"size\":\"200\"}]" # политика и размер, ГБ
|
||||||
|
|
||||||
|
# Edge (сетевой шлюз периметра)
|
||||||
|
nsxt_resource_name = "fullpipe-edge" # имя услуги в ЛК, любое
|
||||||
|
nsxt_vdc_type = "vdc" # родитель: vdc или vdcGroup
|
||||||
|
nsxt_need_enable_avi = true # балансировщик AVI (ALB)
|
||||||
|
nsxt_virtual_services_count = 3 # виртуальных сервисов AVI: 1..4 (Штурвал: не меньше 3)
|
||||||
|
nsxt_ip_addr_pool = "10.10.102.0/24" # пул адресов routed-сети, маска /24
|
||||||
|
nsxt_main_dns = "81.22.46.22" # основной DNS
|
||||||
|
nsxt_second_dns = "185.247.187.77" # второй DNS
|
||||||
|
```
|
||||||
|
|
||||||
|
Описание всех параметров — в `variables.tf`. `terraform.tfvars` с токеном никому не передавайте
|
||||||
|
и не коммитьте в git.
|
||||||
|
|
||||||
|
## 4. Выполните команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform init # один раз — скачает провайдер
|
||||||
|
terraform plan # покажет, что будет создано: 4 ресурса
|
||||||
|
terraform apply # создаст (подтвердить: yes)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Проверьте результат
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform output # UUID и имена созданных услуг
|
||||||
|
```
|
||||||
|
|
||||||
|
И в ЛК: появились vDC и Edge, на организации выделены внешние IP, на шлюзе включён SNAT.
|
||||||
|
Повторный `terraform plan` должен показать `No changes`.
|
||||||
|
|
||||||
|
## 6. Удаление
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform destroy
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядок обратный: SNAT выключается, квота внешних IP обнуляется, затем удаляется шлюз,
|
||||||
|
а vDC приостанавливается (данные сохраняются). **Организация не удаляется.**
|
||||||
|
|
||||||
|
## Файлы примера
|
||||||
|
|
||||||
|
| Файл | Что делает |
|
||||||
|
|---|---|
|
||||||
|
| `versions.tf` | версия Terraform и провайдера Nubes |
|
||||||
|
| `provider.tf` | подключение к API (токен, адрес) |
|
||||||
|
| `variables.tf` | все параметры с описанием |
|
||||||
|
| `vdc.tf` | виртуальный датацентр |
|
||||||
|
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
||||||
|
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
||||||
|
| `outputs.tf` | UUID и имена созданных услуг |
|
||||||
|
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
||||||
|
|
||||||
|
Подробнее про два последних ресурса — на странице
|
||||||
|
[«Ресурсы-модификаторы (IP организации, SNAT)»](../modifiers/org_ip_and_snat.md).
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Примеры Terraform для Nubes
|
||||||
|
|
||||||
|
> ## Внимание: рабочая папка одна
|
||||||
|
>
|
||||||
|
> Для работы используйте **только** [`fullpipe_chain`](fullpipe_chain/) — это пример
|
||||||
|
> «vDC → Edge → внешние IP → SNAT». Он прогнан на живом стенде (создание и удаление)
|
||||||
|
> и снабжён пошаговой инструкцией.
|
||||||
|
>
|
||||||
|
> Остальные папки репозитория — черновики: могут быть сырыми, содержать неактуальные
|
||||||
|
> версии провайдера и работать неправильно. **Не используйте их.**
|
||||||
|
|
||||||
|
Пошаговая инструкция: <https://tf-docs.nodejsk8s.dev.nubes.ru/nubes-dev/curated/pipeline/vdc_edge_ip_snat/>
|
||||||
|
|
||||||
|
## fullpipe_chain — что использовать
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.services.ngcloud.ru/Nail/tf_examples.git
|
||||||
|
cd tf_examples/fullpipe_chain
|
||||||
|
cp terraform.tfvars.example terraform.tfvars # заполнить значениями из ЛК
|
||||||
|
terraform init
|
||||||
|
terraform plan # покажет 4 ресурса, ничего не меняет
|
||||||
|
terraform apply # подтвердить: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Подробности и список значений — в [README примера](fullpipe_chain/README.md).
|
||||||
|
|
||||||
|
Организацию создайте заранее в ЛК: Terraform её не создаёт и не удаляет.
|
||||||
|
|
||||||
|
## Остальные папки — не использовать
|
||||||
|
|
||||||
|
`CRUD`, `modify_resources`, `SHTURVAL_MGMT`, `iot-rmq-demo` — черновики от прошлых работ.
|
||||||
|
Могут быть сырыми и не поддерживаются. Берите только `fullpipe_chain`.
|
||||||
@@ -198,7 +198,8 @@ UUID в облаке не имеет «правильного» регистра
|
|||||||
|
|
||||||
## 10. Куда смотреть дальше
|
## 10. Куда смотреть дальше
|
||||||
|
|
||||||
- `curated/pipeline/vdc_edge_ip_snat.md` — пошаговый разбор цепочки vDC → Edge → IP → SNAT.
|
- [Как развернуть vDC, Edge, внешние IP, SNAT и кластер Штурвал](https://tf-docs.nodejsk8s.dev.nubes.ru/nubes-dev/curated/pipeline/vdc_edge_ip_snat/) —
|
||||||
|
пошаговая инструкция по всей цепочке вашего стенда.
|
||||||
- `curated/modifiers/org_ip_and_snat.md` — ресурсы-модификаторы.
|
- `curated/modifiers/org_ip_and_snat.md` — ресурсы-модификаторы.
|
||||||
- `30_registry/guides/terraform-structure.md` — структура манифестов.
|
- `30_registry/guides/terraform-structure.md` — структура манифестов.
|
||||||
- Внутренние документы (не публикуются): `60_strategy/provider_philosophy.md`,
|
- Внутренние документы (не публикуются): `60_strategy/provider_philosophy.md`,
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# Зависимости облачных сервисов каталога DEV
|
||||||
|
|
||||||
|
Промежуточная инвентаризация для будущего общего графа. Источник — YAML-контракты
|
||||||
|
в `generated/dev/resources_yaml`.
|
||||||
|
|
||||||
|
Вершина — сервис каталога. Направление будущей стрелки: `потребитель -> зависимость`.
|
||||||
|
В таблицу зависимостей включены только связи, явно подтверждённые полем
|
||||||
|
`ref_svc_id` или тем же контрактом сервиса.
|
||||||
|
|
||||||
|
## Все сервисы каталога
|
||||||
|
|
||||||
|
| ID | Сервис | YAML |
|
||||||
|
|---:|---|---|
|
||||||
|
| 1 | Болванка | `1_dummy.yaml` |
|
||||||
|
| 2 | Темплейт k8s | `2_template.yaml` |
|
||||||
|
| 12 | S3 Object Storage | `12_s3.yaml` |
|
||||||
|
| 13 | S3 бакет | `13_s3bucket.yaml` |
|
||||||
|
| 19 | Организация в Cloud Director | `19_vc_org.yaml` |
|
||||||
|
| 21 | Виртуальный датацентр (vDC) | `21_vc_vdc.yaml` |
|
||||||
|
| 22 | Сетевой шлюз периметра (Edge) | `22_vc_nsxt.yaml` |
|
||||||
|
| 25 | Публичные IP адреса | `25_vcexternalip.yaml` |
|
||||||
|
| 26 | Виртуальный каталог ВМ (vApp) | `26_vapp.yaml` |
|
||||||
|
| 28 | Виртуальная машина | `28_vc_vm_v3.yaml` |
|
||||||
|
| 29 | Группа датацентров | `29_vc_vdc_group.yaml` |
|
||||||
|
| 50 | Nextcloud | `50_nextcloud.yaml` |
|
||||||
|
| 81 | Apache Superset | `81_superset.yaml` |
|
||||||
|
| 82 | Container Registry | `82_harbor.yaml` |
|
||||||
|
| 86 | Velero | `86_k8s_velero.yaml` |
|
||||||
|
| 87 | Valkey | `87_k8svalkey.yaml` |
|
||||||
|
| 88 | k8sZitiController | `88_k8s_ziti_controller.yaml` |
|
||||||
|
| 89 | Web-сервер с фреймворком Flask | `89_flask.yaml` |
|
||||||
|
| 90 | PostgreSQL | `90_postgres.yaml` |
|
||||||
|
| 91 | Redis | `91_redis.yaml` |
|
||||||
|
| 92 | MongoDB | `92_mongodb.yaml` |
|
||||||
|
| 93 | RabbitMQ | `93_rabbitmq.yaml` |
|
||||||
|
| 94 | Lucee | `94_lucee.yaml` |
|
||||||
|
| 95 | NodeJS | `95_nodejs.yaml` |
|
||||||
|
| 96 | pgAdmin | `96_pgadmin.yaml` |
|
||||||
|
| 97 | NodeRed | `97_nodered.yaml` |
|
||||||
|
| 98 | Простой HTTP контейнер | `98_http.yaml` |
|
||||||
|
| 99 | Gitea | `99_gitea.yaml` |
|
||||||
|
| 109 | Управление DNS | `109_zones_v2.yaml` |
|
||||||
|
| 111 | DNS запись | `111_dnsrecord.yaml` |
|
||||||
|
| 115 | Mariadb | `115_mariadb.yaml` |
|
||||||
|
| 116 | ApacheKafka | `116_kafka.yaml` |
|
||||||
|
| 119 | Akhq | `119_akhq.yaml` |
|
||||||
|
| 120 | ClickHouse | `120_clickhouse.yaml` |
|
||||||
|
| 148 | Менеджмент Kubernetes кластер Штурвал | `148_vc_mgmt_sthutrval_cluster.yaml` |
|
||||||
|
| 149 | VALO Cloud | `149_valo_tenant.yaml` |
|
||||||
|
| 150 | Kubernetes кластер Штурвал | `150_k8s_sthutrval_cluster.yaml` |
|
||||||
|
| 151 | Vault | `151_k8s_openbao.yaml` |
|
||||||
|
| 153 | Nifi | `153_nifi.yaml` |
|
||||||
|
| 163 | ML Улей | `163_llm_ai.yaml` |
|
||||||
|
|
||||||
|
## Подтверждённые зависимости
|
||||||
|
|
||||||
|
| ID | Потребитель | Зависимость | Поле связи | Смысл связи |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| D-01 | DNS запись (111) | Управление DNS (109) | `zoneUid` | запись создаётся в DNS-зоне |
|
||||||
|
| D-02 | S3 бакет (13) | S3 Object Storage (12) | `s3UserUid` | бакет создаётся для корневой S3-услуги |
|
||||||
|
| D-03 | Виртуальный датацентр (21) | Организация в Cloud Director (19) | `organizationUid` | vDC принадлежит организации |
|
||||||
|
| D-04 | Сетевой шлюз периметра (22) | Виртуальный датацентр (21) | `vdcUid` | Edge привязывается к vDC |
|
||||||
|
| D-05 | Сетевой шлюз периметра (22) | Группа датацентров (29) | `vdcGroupUid` | альтернативная привязка Edge к группе vDC (vdcType=vdcGroup) |
|
||||||
|
| D-06 | Виртуальный каталог ВМ (26) | Сетевой шлюз периметра (22) | `nsxtUid` | vApp использует Edge для сети |
|
||||||
|
| D-07 | Виртуальный каталог ВМ (26) | Виртуальный датацентр (21) | `vdcUid` | vApp размещается в vDC |
|
||||||
|
| D-08 | Виртуальная машина (28) | Виртуальный каталог ВМ (26) | `vappUid` | VM размещается в vApp |
|
||||||
|
| D-09 | Группа датацентров (29) | Виртуальный датацентр (21) | `vdcUid` | группа объединяет vDC (create и add_vdc) |
|
||||||
|
| D-10 | Akhq (119) | ApacheKafka (116) | `kafkaUid` | UI подключается к Kafka-кластеру |
|
||||||
|
| D-11 | Container Registry (82) | S3 Object Storage (12) | `s3Uid` | registry использует S3 для хранения |
|
||||||
|
| D-12 | Gitea (99) | PostgreSQL (90) | `psqlUid` | Gitea использует PostgreSQL |
|
||||||
|
|
||||||
|
## Переиспользование существующих инстансов
|
||||||
|
|
||||||
|
Зависимости (кроме Организации) являются ссылками на **существующие инстансы** через UUID:
|
||||||
|
|
||||||
|
- Новую ВМ (28) можно создать в уже существующем vApp, vDC, Edge — ссылкой `vappUid`/`vdcUid`/`nsxtUid`.
|
||||||
|
- Edge (22) можно переиспользовать, если он привязан к нужному vDC или groupvDC.
|
||||||
|
- Для Штурвала (150) переиспользуемый Edge должен иметь включённый ALB и `virtualServicesCount >= 3`.
|
||||||
|
- Внешние IP резервируются только после: Организация + vDC + Каталог (vApp) + Edge (по `25_vcexternalip.yaml`, `service_man`).
|
||||||
|
|
||||||
|
## Где выделяются ресурсы (CPU / RAM / Storage / IP)
|
||||||
|
|
||||||
|
| Элемент | Где задаётся | Параметр(ы) |
|
||||||
|
|---|---|---|
|
||||||
|
| Пул CPU/RAM/Storage организации | vDC (21) create/modify | `cpuAllocated`, `memAllocated`, `storageConfig` (+ разовый `cpuGuaranteed` 0/50/80) |
|
||||||
|
| Запрос ресурсов нод Штурвала | Кластер Штурвал (150) | `controlPlaneConfiguration.sizingPolicy/sizingDisk/count`, `workerConfiguration…` (политики из vDC) |
|
||||||
|
| Запрос ресурсов ВМ | Виртуальная машина (28) | `vmCpu`, `vmRam`, `vmDisk` (доп. диск) |
|
||||||
|
| Внешние IP | vcOrg (19) `modify` (`vIPConfigure`) или `vcexternalip` (25) | `ipSpaceName`, квота адресов |
|
||||||
|
| SNAT-правило | Edge (22) `modify` | `ipSpaceName` |
|
||||||
|
| DNAT/SNAT-правила адреса | Публичные IP (25) | `dnatCreate`/`snatCreate`, `internalAddrAccess`, `internalPortAccess` |
|
||||||
|
|
||||||
|
## Чек-лист создания Штурвала (150) — по `service_man`
|
||||||
|
|
||||||
|
1. Организация (19) — create.
|
||||||
|
2. vDC (21) — create, выделить ресурсы под все ноды.
|
||||||
|
3. Edge (22) — create, включить ALB и `virtualServicesCount >= 3`.
|
||||||
|
4. Внешние адреса в организации — vcOrg `modify`, суммарно 3 адреса.
|
||||||
|
5. SNAT — Edge `modify`, выбрать `ipSpaceName`.
|
||||||
|
6. Кластер Штурвал (150) — create (требует `vdcUid` и `nsxtUid`).
|
||||||
|
|
||||||
|
## Чек-лист создания ВМ (28) — по create-параметрам
|
||||||
|
|
||||||
|
1. vDC (21) — существующий (`vdcUid`).
|
||||||
|
2. Edge (22) — существующий (`nsxtUid`).
|
||||||
|
3. vApp (26) — существующий (`vappUid`), привязан к vDC и Edge.
|
||||||
|
4. ВМ (28) — create; обязательные: `vappUid`, `vmName`, `vmCpu`, `vmRam`, `accessPortList`, `imageVm`, `userLogin`, `userPublicKey`, `ipSpaceName`.
|
||||||
|
|
||||||
|
## Правила для будущего графа
|
||||||
|
|
||||||
|
1. Рисовать стрелку только по подтверждённой связи сервиса каталога.
|
||||||
|
2. `ref_svc_id` считать прямой зависимостью; `descr` использовать для подписи
|
||||||
|
стрелки и проверки смысла.
|
||||||
|
3. Не считать общей платформой, DNS-полем или внешним IP автоматическую связь
|
||||||
|
между сервисами без ссылки на конкретный сервисный ID.
|
||||||
|
4. Поля без `ref_svc_id` вынести в отдельный список кандидатов на проверку, но не
|
||||||
|
смешивать с подтверждёнными рёбрами.
|
||||||
@@ -1,17 +1,33 @@
|
|||||||
# Как развернуть vDC, Edge, внешние IP и SNAT
|
# Как развернуть vDC, Edge, внешние IP, SNAT и кластер Штурвал
|
||||||
|
|
||||||
Пошаговая инструкция. Готовые файлы примера — в репозитории `tf_examples`, папка `fullpipe_chain`.
|
Пошаговая инструкция. Готовые файлы примера — в репозитории `tf_examples`, папка `fullpipe_chain`.
|
||||||
|
|
||||||
Что получится в итоге:
|
Что получится в итоге:
|
||||||
|
|
||||||
- виртуальный датацентр (vDC);
|
- виртуальный датацентр (vDC);
|
||||||
- сетевой шлюз периметра (Edge);
|
- сетевой шлюз периметра (Edge) с балансировщиком AVI;
|
||||||
- внешние IP на организации;
|
- внешние IP на организации;
|
||||||
- SNAT на шлюзе.
|
- SNAT на шлюзе;
|
||||||
|
- Kubernetes-кластер Штурвал (сервис 150) на этой сети.
|
||||||
Кластер Штурвал в эту инструкцию не входит — он разворачивается долго, отдельным шагом.
|
|
||||||
|
|
||||||
**Организацию создайте заранее в ЛК** — Terraform её не создаёт и не удаляет.
|
**Организацию создайте заранее в ЛК** — Terraform её не создаёт и не удаляет.
|
||||||
|
Кластер Штурвал создаётся десятки минут, поэтому провайдер ждёт его до часу
|
||||||
|
(`operation_timeout = "60m"`); остальные ресурсы — минуты.
|
||||||
|
|
||||||
|
## Что нужно перед началом
|
||||||
|
|
||||||
|
| Требование | Зачем | Где смотреть |
|
||||||
|
|---|---|---|
|
||||||
|
| Terraform 1.5 или новее | работает провайдер | `terraform version` |
|
||||||
|
| Токен API | доступ к ЛК | ЛК → Профиль → Токены → «Технический» |
|
||||||
|
| Организация в Cloud Director | всё создаётся внутри неё | услуга «Организация в Cloud Director» |
|
||||||
|
| Edge с балансировщиком AVI | без ALB кластер Штурвал не поднимется | `nsxt_need_enable_avi = true`, `nsxt_virtual_services_count >= 3` |
|
||||||
|
| Не меньше 3 внешних IP | адрес Kubernetes API, адрес Ingress и запас | `ip_count = "3"` |
|
||||||
|
| SNAT на Edge | выход в интернет для машин кластера | ресурс `nubes_vc_nsxt_snat` |
|
||||||
|
|
||||||
|
Порядок из чек-листа услуги 150 (именно так связаны ресурсы в примере):
|
||||||
|
организация → vDC → Edge (ALB, AVI ≥ 3) → внешние IP (≥ 3) → SNAT → кластер Штурвал.
|
||||||
|
Минимум для кластера: 1 мастер-нода и 1 воркер-нода по 4 vCPU / 8 ГБ RAM / 50 ГБ диска.
|
||||||
|
|
||||||
## 1. Скачайте пример
|
## 1. Скачайте пример
|
||||||
|
|
||||||
@@ -79,7 +95,7 @@ nsxt_second_dns = "185.247.187.77" # второй DNS
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
terraform init # один раз — скачает провайдер
|
terraform init # один раз — скачает провайдер
|
||||||
terraform plan # покажет, что будет создано: 4 ресурса
|
terraform plan # покажет, что будет создано: 5 ресурсов
|
||||||
terraform apply # создаст (подтвердить: yes)
|
terraform apply # создаст (подтвердить: yes)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -89,17 +105,37 @@ terraform apply # создаст (подтвердить: yes)
|
|||||||
terraform output # UUID и имена созданных услуг
|
terraform output # UUID и имена созданных услуг
|
||||||
```
|
```
|
||||||
|
|
||||||
И в ЛК: появились vDC и Edge, на организации выделены внешние IP, на шлюзе включён SNAT.
|
И в ЛК: появились vDC, Edge и кластер Штурвал, на организации выделены внешние IP,
|
||||||
Повторный `terraform plan` должен показать `No changes`.
|
на шлюзе включён SNAT. Повторный `terraform plan` должен показать `No changes`.
|
||||||
|
|
||||||
## 6. Удаление
|
Кластер создаётся десятки минут — провайдер ждёт его (`operation_timeout = "60m"`),
|
||||||
|
в ЛК он появится со статусом `running`. Адреса Kubernetes API и Ingress — в
|
||||||
|
`terraform output shturval_state_params` (поля `kubernetesApiAddress` и `ingressAddress`).
|
||||||
|
|
||||||
|
## 6. Удаление: «заморозка» вместо удаления
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
terraform destroy
|
terraform destroy
|
||||||
```
|
```
|
||||||
|
|
||||||
Порядок обратный: SNAT выключается, квота внешних IP обнуляется, затем удаляется шлюз,
|
По умолчанию пример повторяет рабочую конфигурацию — при `destroy` объекты **не удаляются**:
|
||||||
а vDC приостанавливается (данные сохраняются). **Организация не удаляется.**
|
|
||||||
|
| Ресурс | Что делает `destroy` | Флаг в примере |
|
||||||
|
|---|---|---|
|
||||||
|
| Кластер Штурвал | `suspend`: выключается, данные и адреса сохраняются | `suspend_on_destroy = true` |
|
||||||
|
| vDC | `suspend` | `suspend_on_destroy = true` |
|
||||||
|
| Edge | не трогается: у эджа нет операции `suspend` | `keep_on_destroy = true` |
|
||||||
|
| SNAT | не выключается | `keep_on_destroy = true` |
|
||||||
|
| Квота внешних IP | не меняется: адреса держит кластер Штурвала | `keep_on_destroy = true` |
|
||||||
|
|
||||||
|
Приоритет флагов: `keep_on_destroy` важнее `suspend_on_destroy`. Следующий `apply`
|
||||||
|
усыновит объекты по имени и разморозит кластер и vDC
|
||||||
|
(`adopt_existing_on_create = true` → `resume`). **Организация не удаляется никогда.**
|
||||||
|
|
||||||
|
Полное удаление — осознанно: поставьте `keep_on_destroy = false` и
|
||||||
|
`suspend_on_destroy = false` и удаляйте по порядку: кластер → квота IP (`count = 0`) →
|
||||||
|
SNAT → Edge → vDC. Квоту нельзя опустить ниже занятых адресов, поэтому — только
|
||||||
|
после удаления кластера; vDC удаляется лишь через 14 дней после `suspend`.
|
||||||
|
|
||||||
## Файлы примера
|
## Файлы примера
|
||||||
|
|
||||||
@@ -111,7 +147,8 @@ terraform destroy
|
|||||||
| `vdc.tf` | виртуальный датацентр |
|
| `vdc.tf` | виртуальный датацентр |
|
||||||
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
||||||
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
||||||
| `outputs.tf` | UUID и имена созданных услуг |
|
| `shturval.tf` | Kubernetes-кластер Штурвал: переменные Штурвала, группы воркеров и сам ресурс |
|
||||||
|
| `outputs.tf` | UUID и имена созданных услуг (vDC, Edge, Штурвал) |
|
||||||
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
||||||
|
|
||||||
Подробнее про два последних ресурса — на странице
|
Подробнее про два последних ресурса — на странице
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
flowchart LR
|
||||||
|
classDef base fill:#e1f5fe,stroke:#0288d1,stroke-width:2px;
|
||||||
|
classDef net fill:#ede7f6,stroke:#5e35b1,stroke-width:2px;
|
||||||
|
classDef compute fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
|
||||||
|
classDef target fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
|
||||||
|
classDef note fill:#fafafa,stroke:#9e9e9e,stroke-width:1px,stroke-dasharray: 4 4;
|
||||||
|
|
||||||
|
subgraph S1 ["Шаг 1. Тенант"]
|
||||||
|
ORG["<b>Организация (vcOrg: 19)</b><br/>• Тип: iaas / saas"]:::base
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph S2 ["Шаг 2. Пул ресурсов"]
|
||||||
|
VDC["<b>Виртуальный ДЦ (vcVdc: 21)</b><br/>• cpuGuaranteed: 0% / 50% / 80%<br/>• Пул: cpuAllocated, memAllocated, storage"]:::compute
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph S3 ["Шаг 3. Сетевой периметр"]
|
||||||
|
EDGE["<b>Шлюз Edge (vcNsxt: 22)</b><br/>• AVI Load Balancer<br/>• <i>modify:</i> SNAT (ipSpaceName)"]:::net
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph S4 ["Шаг 4. Среда запуска и адреса"]
|
||||||
|
VAPP["<b>Каталог vApp (26)</b><br/>(контейнер для ВМ)"]:::compute
|
||||||
|
IP["<b>Внешние IP</b><br/>• vcOrg modify / 25<br/>• квота адресов (ipSpace)"]:::note
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph S5 ["Шаг 5. Потребители"]
|
||||||
|
VM["<b>Виртуальная машина (28)</b><br/>• vmCpu, vmRam, vmDisk"]:::target
|
||||||
|
SHTURVAL["<b>Кластер Штурвал (150)</b><br/>• sizingPolicy, sizingDisk, count"]:::target
|
||||||
|
end
|
||||||
|
|
||||||
|
ORG -->|"organizationUid"| VDC
|
||||||
|
VDC -->|"vdcUid"| EDGE
|
||||||
|
ORG -.->|"modify: vIPConfigure"| IP
|
||||||
|
EDGE -.->|"modify: SNAT (ipSpaceName)"| IP
|
||||||
|
|
||||||
|
VDC -->|"vdcUid"| VAPP
|
||||||
|
EDGE -->|"nsxtUid"| VAPP
|
||||||
|
|
||||||
|
VAPP -->|"vappUid"| VM
|
||||||
|
IP -.->|"внешний IP"| VM
|
||||||
|
|
||||||
|
VDC -->|"vdcUid"| SHTURVAL
|
||||||
|
EDGE -->|"nsxtUid"| SHTURVAL
|
||||||
|
IP -.->|"внешний IP (>= 3)"| SHTURVAL
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg id="mermaid-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 2338.671875px;" viewBox="0 0 2338.671875 552" role="graphics-document document" aria-roledescription="flowchart-v2" xmlns:xlink="http://www.w3.org/1999/xlink"><style xmlns="http://www.w3.org/1999/xhtml">@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css");</style><style>#mermaid-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg .error-icon{fill:#552222;}#mermaid-svg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg .marker{fill:#333333;stroke:#333333;}#mermaid-svg .marker.cross{stroke:#333333;}#mermaid-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg p{margin:0;}#mermaid-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg .cluster-label text{fill:#333;}#mermaid-svg .cluster-label span{color:#333;}#mermaid-svg .cluster-label span p{background-color:transparent;}#mermaid-svg .label text,#mermaid-svg span{fill:#333;color:#333;}#mermaid-svg .node rect,#mermaid-svg .node circle,#mermaid-svg .node ellipse,#mermaid-svg .node polygon,#mermaid-svg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg .rough-node .label text,#mermaid-svg .node .label text,#mermaid-svg .image-shape .label,#mermaid-svg .icon-shape .label{text-anchor:middle;}#mermaid-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg .rough-node .label,#mermaid-svg .node .label,#mermaid-svg .image-shape .label,#mermaid-svg .icon-shape .label{text-align:center;}#mermaid-svg .node.clickable{cursor:pointer;}#mermaid-svg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg .arrowheadPath{fill:#333333;}#mermaid-svg .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-svg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg .cluster text{fill:#333;}#mermaid-svg .cluster span{color:#333;}#mermaid-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg rect.text{fill:none;stroke-width:0;}#mermaid-svg .icon-shape,#mermaid-svg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg .icon-shape p,#mermaid-svg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg .icon-shape .label rect,#mermaid-svg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg .node .neo-node{stroke:#9370DB;}#mermaid-svg [data-look="neo"].node rect,#mermaid-svg [data-look="neo"].cluster rect,#mermaid-svg [data-look="neo"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-svg [data-look="neo"].swimlane.cluster rect{filter:none;}#mermaid-svg [data-look="neo"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-svg [data-look="neo"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-svg [data-look="neo"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-svg [data-look="neo"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-svg [data-look="neo"].node circle .state-start{fill:#000000;}#mermaid-svg [data-look="neo"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg .base>*{fill:rgb(225, 245, 254)!important;stroke:rgb(2, 136, 209)!important;stroke-width:2px!important;}#mermaid-svg .base span{fill:rgb(225, 245, 254)!important;stroke:rgb(2, 136, 209)!important;stroke-width:2px!important;}#mermaid-svg .net>*{fill:rgb(237, 231, 246)!important;stroke:rgb(94, 53, 177)!important;stroke-width:2px!important;}#mermaid-svg .net span{fill:rgb(237, 231, 246)!important;stroke:rgb(94, 53, 177)!important;stroke-width:2px!important;}#mermaid-svg .compute>*{fill:rgb(255, 243, 224)!important;stroke:rgb(245, 124, 0)!important;stroke-width:2px!important;}#mermaid-svg .compute span{fill:rgb(255, 243, 224)!important;stroke:rgb(245, 124, 0)!important;stroke-width:2px!important;}#mermaid-svg .target>*{fill:rgb(232, 245, 233)!important;stroke:rgb(46, 125, 50)!important;stroke-width:2px!important;}#mermaid-svg .target span{fill:rgb(232, 245, 233)!important;stroke:rgb(46, 125, 50)!important;stroke-width:2px!important;}#mermaid-svg .note>*{fill:rgb(250, 250, 250)!important;stroke:rgb(158, 158, 158)!important;stroke-width:1px!important;stroke-dasharray:4,4!important;}#mermaid-svg .note span{fill:rgb(250, 250, 250)!important;stroke:rgb(158, 158, 158)!important;stroke-width:1px!important;stroke-dasharray:4,4!important;}</style><g><marker id="mermaid-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="mermaid-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"/></marker><marker id="mermaid-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"/></marker><g class="root"><g class="clusters"><g class="cluster " id="mermaid-svg-S5" data-look="classic"><rect style="" x="2020.671875" y="60" width="310" height="449"/><g class="cluster-label " transform="translate(2101.4140625, 60)"><foreignObject width="148.515625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel "><p>Шаг 5. Потребители</p></span></div></foreignObject></g></g><g class="cluster " id="mermaid-svg-S4" data-look="classic"><rect style="" x="1539.546875" y="37" width="298.9375" height="322"/><g class="cluster-label " transform="translate(1573.4921875, 37)"><foreignObject width="231.046875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel "><p>Шаг 4. Среда запуска и адреса</p></span></div></foreignObject></g></g><g class="cluster " id="mermaid-svg-S3" data-look="classic"><rect style="" x="979.546875" y="98" width="310" height="276"/><g class="cluster-label " transform="translate(1039.9453125, 98)"><foreignObject width="189.203125" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel "><p>Шаг 3. Сетевой периметр</p></span></div></foreignObject></g></g><g class="cluster " id="mermaid-svg-S2" data-look="classic"><rect style="" x="471.03125" y="178" width="310" height="366"/><g class="cluster-label " transform="translate(549.703125, 178)"><foreignObject width="152.65625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel "><p>Шаг 2. Пул ресурсов</p></span></div></foreignObject></g></g><g class="cluster " id="mermaid-svg-S1" data-look="classic"><rect style="" x="8" y="8" width="301.84375" height="403"/><g class="cluster-label " transform="translate(107.265625, 8)"><foreignObject width="103.3125" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel "><p>Шаг 1. Тенант</p></span></div></foreignObject></g></g></g><g class="edgePaths"><path d="M201.574,265L219.619,281.5C237.664,298,273.754,331,305.231,347.5C336.708,364,363.573,364,390.438,364C417.302,364,444.167,364,461.099,364C478.031,364,485.031,364,488.531,364L492.031,364" id="mermaid-svg-L_ORG_VDC_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_ORG_VDC_0" data-points="W3sieCI6MjAxLjU3MzcwOTIzOTEzMDQ0LCJ5IjoyNjV9LHsieCI6MzA5Ljg0Mzc1LCJ5IjozNjR9LHsieCI6MzkwLjQzNzUsInkiOjM2NH0seyJ4Ijo0NzEuMDMxMjUsInkiOjM2NH0seyJ4Ijo0OTYuMDMxMjUsInkiOjM2NH1d" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M740.311,277L747.098,271.833C753.884,266.667,767.458,256.333,790.787,251.167C814.117,246,847.203,246,880.289,246C913.375,246,946.461,246,966.504,246C986.547,246,993.547,246,997.047,246L1000.547,246" id="mermaid-svg-L_VDC_EDGE_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_VDC_EDGE_0" data-points="W3sieCI6NzQwLjMxMDkxMTAxNjk0OTEsInkiOjI3N30seyJ4Ijo3ODEuMDMxMjUsInkiOjI0Nn0seyJ4Ijo4ODAuMjg5MDYyNSwieSI6MjQ2fSx7IngiOjk3OS41NDY4NzUsInkiOjI0Nn0seyJ4IjoxMDA0LjU0Njg3NSwieSI6MjQ2fV0=" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M195.481,187L214.541,166.667C233.602,146.333,271.723,105.667,304.216,85.333C336.708,65,363.573,65,390.438,65C417.302,65,444.167,65,483.432,65C522.698,65,574.365,65,626.031,65C677.698,65,729.365,65,771.741,65C814.117,65,847.203,65,880.289,65C913.375,65,946.461,65,988.837,65C1031.214,65,1082.88,65,1134.547,65C1186.214,65,1237.88,65,1284.547,78.333C1331.214,91.667,1372.88,118.333,1414.547,131.667C1456.214,145,1497.88,145,1522.221,144.484C1546.561,143.968,1553.575,142.935,1557.082,142.419L1560.59,141.903" id="mermaid-svg-L_ORG_IP_0" class=" edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_ORG_IP_0" data-points="W3sieCI6MTk1LjQ4MDU5MDA2MjExMTgsInkiOjE4N30seyJ4IjozMDkuODQzNzUsInkiOjY1fSx7IngiOjM5MC40Mzc1LCJ5Ijo2NX0seyJ4Ijo0NzEuMDMxMjUsInkiOjY1fSx7IngiOjYyNi4wMzEyNSwieSI6NjV9LHsieCI6NzgxLjAzMTI1LCJ5Ijo2NX0seyJ4Ijo4ODAuMjg5MDYyNSwieSI6NjV9LHsieCI6OTc5LjU0Njg3NSwieSI6NjV9LHsieCI6MTEzNC41NDY4NzUsInkiOjY1fSx7IngiOjEyODkuNTQ2ODc1LCJ5Ijo2NX0seyJ4IjoxNDE0LjU0Njg3NSwieSI6MTQ1fSx7IngiOjE1MzkuNTQ2ODc1LCJ5IjoxNDV9LHsieCI6MTU2NC41NDY4NzUsInkiOjE0MS4zMjAzMDEwNjYyNzY0fV0=" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1258.154,183L1263.387,180.333C1268.619,177.667,1279.083,172.333,1305.148,158.667C1331.214,145,1372.88,123,1414.547,112C1456.214,101,1497.88,101,1522.221,101.516C1546.561,102.032,1553.575,103.065,1557.082,103.581L1560.59,104.097" id="mermaid-svg-L_EDGE_IP_0" class=" edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_EDGE_IP_0" data-points="W3sieCI6MTI1OC4xNTQ0Njk5MzY3MDksInkiOjE4M30seyJ4IjoxMjg5LjU0Njg3NSwieSI6MTY3fSx7IngiOjE0MTQuNTQ2ODc1LCJ5IjoxMDF9LHsieCI6MTUzOS41NDY4NzUsInkiOjEwMX0seyJ4IjoxNTY0LjU0Njg3NSwieSI6MTA0LjY3OTY5ODkzMzcyMzZ9XQ==" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M756.031,399.226L760.198,400.355C764.365,401.484,772.698,403.742,793.408,404.871C814.117,406,847.203,406,880.289,406C913.375,406,946.461,406,988.837,406C1031.214,406,1082.88,406,1134.547,406C1186.214,406,1237.88,406,1284.547,390.333C1331.214,374.667,1372.88,343.333,1414.547,327.667C1456.214,312,1497.88,312,1525.684,310.741C1553.487,309.482,1567.428,306.964,1574.398,305.704L1581.368,304.445" id="mermaid-svg-L_VDC_VAPP_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_VDC_VAPP_0" data-points="W3sieCI6NzU2LjAzMTI1LCJ5IjozOTkuMjI1ODA2NDUxNjEyOX0seyJ4Ijo3ODEuMDMxMjUsInkiOjQwNn0seyJ4Ijo4ODAuMjg5MDYyNSwieSI6NDA2fSx7IngiOjk3OS41NDY4NzUsInkiOjQwNn0seyJ4IjoxMTM0LjU0Njg3NSwieSI6NDA2fSx7IngiOjEyODkuNTQ2ODc1LCJ5Ijo0MDZ9LHsieCI6MTQxNC41NDY4NzUsInkiOjMxMn0seyJ4IjoxNTM5LjU0Njg3NSwieSI6MzEyfSx7IngiOjE1ODUuMzA0Njg3NSwieSI6MzAzLjczNDMxOTQ2NDc3MTF9XQ==" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1264.547,224.194L1268.714,223.495C1272.88,222.796,1281.214,221.398,1306.214,220.699C1331.214,220,1372.88,220,1414.547,220C1456.214,220,1497.88,220,1528.067,224.067C1558.253,228.135,1576.96,236.27,1586.313,240.337L1595.666,244.405" id="mermaid-svg-L_EDGE_VAPP_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_EDGE_VAPP_0" data-points="W3sieCI6MTI2NC41NDY4NzUsInkiOjIyNC4xOTM1NDgzODcwOTY3N30seyJ4IjoxMjg5LjU0Njg3NSwieSI6MjIwfSx7IngiOjE0MTQuNTQ2ODc1LCJ5IjoyMjB9LHsieCI6MTUzOS41NDY4NzUsInkiOjIyMH0seyJ4IjoxNTk5LjMzNDM3NSwieSI6MjQ2fV0=" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1792.727,285L1800.353,285C1807.979,285,1823.232,285,1846.04,285C1868.849,285,1899.214,285,1929.578,285C1959.943,285,1990.307,285,2019.627,274.237C2048.947,263.474,2077.222,241.949,2091.36,231.186L2105.498,220.423" id="mermaid-svg-L_VAPP_VM_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_VAPP_VM_0" data-points="W3sieCI6MTc5Mi43MjY1NjI1LCJ5IjoyODV9LHsieCI6MTgzOC40ODQzNzUsInkiOjI4NX0seyJ4IjoxOTI5LjU3ODEyNSwieSI6Mjg1fSx7IngiOjIwMjAuNjcxODc1LCJ5IjoyODV9LHsieCI6MjEwOC42ODAzNDk1NzYyNzEsInkiOjIxOH1d" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1813.484,123L1817.651,123C1821.818,123,1830.151,123,1849.5,123C1868.849,123,1899.214,123,1929.578,123C1959.943,123,1990.307,123,2009.015,124.001C2027.723,125.001,2034.773,127.003,2038.299,128.004L2041.824,129.004" id="mermaid-svg-L_IP_VM_0" class=" edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_IP_VM_0" data-points="W3sieCI6MTgxMy40ODQzNzUsInkiOjEyM30seyJ4IjoxODM4LjQ4NDM3NSwieSI6MTIzfSx7IngiOjE5MjkuNTc4MTI1LCJ5IjoxMjN9LHsieCI6MjAyMC42NzE4NzUsInkiOjEyM30seyJ4IjoyMDQ1LjY3MTg3NSwieSI6MTMwLjA5Njc3NDE5MzU0ODM4fV0=" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M756.031,441.161L760.198,443.634C764.365,446.108,772.698,451.054,793.408,453.527C814.117,456,847.203,456,880.289,456C913.375,456,946.461,456,988.837,456C1031.214,456,1082.88,456,1134.547,456C1186.214,456,1237.88,456,1284.547,456C1331.214,456,1372.88,456,1414.547,456C1456.214,456,1497.88,456,1543.625,456C1589.37,456,1639.193,456,1689.016,456C1738.839,456,1788.661,456,1828.755,456C1868.849,456,1899.214,456,1929.578,456C1959.943,456,1990.307,456,2011.337,453.434C2032.368,450.869,2044.063,445.738,2049.911,443.172L2055.759,440.607" id="mermaid-svg-L_VDC_SHTURVAL_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_VDC_SHTURVAL_0" data-points="W3sieCI6NzU2LjAzMTI1LCJ5Ijo0NDEuMTYxMjkwMzIyNTgwNn0seyJ4Ijo3ODEuMDMxMjUsInkiOjQ1Nn0seyJ4Ijo4ODAuMjg5MDYyNSwieSI6NDU2fSx7IngiOjk3OS41NDY4NzUsInkiOjQ1Nn0seyJ4IjoxMTM0LjU0Njg3NSwieSI6NDU2fSx7IngiOjEyODkuNTQ2ODc1LCJ5Ijo0NTZ9LHsieCI6MTQxNC41NDY4NzUsInkiOjQ1Nn0seyJ4IjoxNTM5LjU0Njg3NSwieSI6NDU2fSx7IngiOjE2ODkuMDE1NjI1LCJ5Ijo0NTZ9LHsieCI6MTgzOC40ODQzNzUsInkiOjQ1Nn0seyJ4IjoxOTI5LjU3ODEyNSwieSI6NDU2fSx7IngiOjIwMjAuNjcxODc1LCJ5Ijo0NTZ9LHsieCI6MjA1OS40MjE4NzUsInkiOjQzOX1d" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1264.547,303.871L1268.714,305.726C1272.88,307.581,1281.214,311.29,1306.214,325.812C1331.214,340.333,1372.88,365.667,1414.547,378.333C1456.214,391,1497.88,391,1543.625,391C1589.37,391,1639.193,391,1689.016,391C1738.839,391,1788.661,391,1828.755,391C1868.849,391,1899.214,391,1929.578,391C1959.943,391,1990.307,391,2008.99,390.932C2027.672,390.865,2034.672,390.729,2038.172,390.661L2041.673,390.594" id="mermaid-svg-L_EDGE_SHTURVAL_0" class=" edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_EDGE_SHTURVAL_0" data-points="W3sieCI6MTI2NC41NDY4NzUsInkiOjMwMy44NzA5Njc3NDE5MzU1fSx7IngiOjEyODkuNTQ2ODc1LCJ5IjozMTV9LHsieCI6MTQxNC41NDY4NzUsInkiOjM5MX0seyJ4IjoxNTM5LjU0Njg3NSwieSI6MzkxfSx7IngiOjE2ODkuMDE1NjI1LCJ5IjozOTF9LHsieCI6MTgzOC40ODQzNzUsInkiOjM5MX0seyJ4IjoxOTI5LjU3ODEyNSwieSI6MzkxfSx7IngiOjIwMjAuNjcxODc1LCJ5IjozOTF9LHsieCI6MjA0NS42NzE4NzUsInkiOjM5MC41MTYxMjkwMzIyNTgwNX1d" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/><path d="M1725.143,174L1744.033,200.667C1762.924,227.333,1800.704,280.667,1834.776,307.333C1868.849,334,1899.214,334,1929.578,334C1959.943,334,1990.307,334,2009.027,335.232C2027.746,336.465,2034.82,338.929,2038.357,340.161L2041.895,341.394" id="mermaid-svg-L_IP_SHTURVAL_0" class=" edge-thickness-normal edge-pattern-dotted edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_IP_SHTURVAL_0" data-points="W3sieCI6MTcyNS4xNDMxNDI3NzI1MTIsInkiOjE3NH0seyJ4IjoxODM4LjQ4NDM3NSwieSI6MzM0fSx7IngiOjE5MjkuNTc4MTI1LCJ5IjozMzR9LHsieCI6MjAyMC42NzE4NzUsInkiOjMzNH0seyJ4IjoyMDQ1LjY3MTg3NSwieSI6MzQyLjcwOTY3NzQxOTM1NDh9XQ==" data-look="classic" marker-end="url(#mermaid-svg_flowchart-v2-pointEnd)"/></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(390.4375, 364)"><g class="label" data-id="L_ORG_VDC_0" transform="translate(-55.59375, -12)"><foreignObject width="111.1875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>organizationUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(880.2890625, 246)"><g class="label" data-id="L_VDC_EDGE_0" transform="translate(-24.453125, -12)"><foreignObject width="48.90625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>vdcUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(880.2890625, 65)"><g class="label" data-id="L_ORG_IP_0" transform="translate(-74.2578125, -12)"><foreignObject width="148.515625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>modify: vIPConfigure</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1414.546875, 101)"><g class="label" data-id="L_EDGE_IP_0" transform="translate(-100, -24)"><foreignObject width="200" height="48"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;"><span class="edgeLabel "><p>modify: SNAT (ipSpaceName)</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1134.546875, 406)"><g class="label" data-id="L_VDC_VAPP_0" transform="translate(-24.453125, -12)"><foreignObject width="48.90625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>vdcUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1414.546875, 220)"><g class="label" data-id="L_EDGE_VAPP_0" transform="translate(-26.6796875, -12)"><foreignObject width="53.359375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>nsxtUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1929.578125, 285)"><g class="label" data-id="L_VAPP_VM_0" transform="translate(-29.3515625, -12)"><foreignObject width="58.703125" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>vappUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1929.578125, 123)"><g class="label" data-id="L_IP_VM_0" transform="translate(-42.671875, -12)"><foreignObject width="85.34375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>внешний IP</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1414.546875, 456)"><g class="label" data-id="L_VDC_SHTURVAL_0" transform="translate(-24.453125, -12)"><foreignObject width="48.90625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>vdcUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1689.015625, 391)"><g class="label" data-id="L_EDGE_SHTURVAL_0" transform="translate(-26.6796875, -12)"><foreignObject width="53.359375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>nsxtUid</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(1929.578125, 334)"><g class="label" data-id="L_IP_SHTURVAL_0" transform="translate(-66.09375, -12)"><foreignObject width="132.1875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel "><p>внешний IP (>= 3)</p></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default base " id="mermaid-svg-flowchart-ORG-0" data-look="classic" transform="translate(158.921875, 226)"><rect class="basic label-container" style="fill:#e1f5fe !important;stroke:#0288d1 !important;stroke-width:2px !important" x="-125.921875" y="-39" width="251.84375" height="78"/><g class="label" style="" transform="translate(-95.921875, -24)"><rect/><foreignObject width="191.84375" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel "><p><b>Организация (vcOrg: 19)</b><br />• Тип: iaas / saas</p></span></div></foreignObject></g></g><g class="node default compute " id="mermaid-svg-flowchart-VDC-1" data-look="classic" transform="translate(626.03125, 364)"><rect class="basic label-container" style="fill:#fff3e0 !important;stroke:#f57c00 !important;stroke-width:2px !important" x="-130" y="-87" width="260" height="174"/><g class="label" style="" transform="translate(-100, -72)"><rect/><foreignObject width="200" height="144"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;"><span class="nodeLabel "><p><b>Виртуальный ДЦ (vcVdc: 21)</b><br />• cpuGuaranteed: 0% / 50% / 80%<br />• Пул: cpuAllocated, memAllocated, storage</p></span></div></foreignObject></g></g><g class="node default net " id="mermaid-svg-flowchart-EDGE-2" data-look="classic" transform="translate(1134.546875, 246)"><rect class="basic label-container" style="fill:#ede7f6 !important;stroke:#5e35b1 !important;stroke-width:2px !important" x="-130" y="-63" width="260" height="126"/><g class="label" style="" transform="translate(-100, -48)"><rect/><foreignObject width="200" height="96"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;"><span class="nodeLabel "><p><b>Шлюз Edge (vcNsxt: 22)</b><br />• AVI Load Balancer<br />• <i>modify:</i> SNAT (ipSpaceName)</p></span></div></foreignObject></g></g><g class="node default compute " id="mermaid-svg-flowchart-VAPP-3" data-look="classic" transform="translate(1689.015625, 285)"><rect class="basic label-container" style="fill:#fff3e0 !important;stroke:#f57c00 !important;stroke-width:2px !important" x="-103.7109375" y="-39" width="207.421875" height="78"/><g class="label" style="" transform="translate(-73.7109375, -24)"><rect/><foreignObject width="147.421875" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel "><p><b>Каталог vApp (26)</b><br />(контейнер для ВМ)</p></span></div></foreignObject></g></g><g class="node default note " id="mermaid-svg-flowchart-IP-4" data-look="classic" transform="translate(1689.015625, 123)"><rect class="basic label-container" style="fill:#fafafa !important;stroke:#9e9e9e !important;stroke-width:1px !important;stroke-dasharray:4 4 !important" x="-124.46875" y="-51" width="248.9375" height="102"/><g class="label" style="" transform="translate(-94.46875, -36)"><rect/><foreignObject width="188.9375" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="nodeLabel "><p><b>Внешние IP</b><br />• vcOrg modify / 25<br />• квота адресов (ipSpace)</p></span></div></foreignObject></g></g><g class="node default target " id="mermaid-svg-flowchart-VM-5" data-look="classic" transform="translate(2175.671875, 167)"><rect class="basic label-container" style="fill:#e8f5e9 !important;stroke:#2e7d32 !important;stroke-width:2px !important" x="-130" y="-51" width="260" height="102"/><g class="label" style="" transform="translate(-100, -36)"><rect/><foreignObject width="200" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;"><span class="nodeLabel "><p><b>Виртуальная машина (28)</b><br />• vmCpu, vmRam, vmDisk</p></span></div></foreignObject></g></g><g class="node default target " id="mermaid-svg-flowchart-SHTURVAL-6" data-look="classic" transform="translate(2175.671875, 388)"><rect class="basic label-container" style="fill:#e8f5e9 !important;stroke:#2e7d32 !important;stroke-width:2px !important" x="-130" y="-51" width="260" height="102"/><g class="label" style="" transform="translate(-100, -36)"><rect/><foreignObject width="200" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 200px; text-align: center; width: 200px;"><span class="nodeLabel "><p><b>Кластер Штурвал (150)</b><br />• sizingPolicy, sizingDisk, count</p></span></div></foreignObject></g></g></g></g></g><defs><filter id="mermaid-svg-drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><defs><filter id="mermaid-svg-drop-shadow-small" height="150%" width="150%"><feDropShadow dx="2" dy="2" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs></svg>
|
||||||
|
After Width: | Height: | Size: 32 KiB |
+2
-1
@@ -56,9 +56,10 @@ nav:
|
|||||||
- Руководства:
|
- Руководства:
|
||||||
- Быстрый старт: 30_registry/guides/getting-started.md
|
- Быстрый старт: 30_registry/guides/getting-started.md
|
||||||
- Основы Terraform: 30_registry/guides/terraform-basics.md
|
- Основы Terraform: 30_registry/guides/terraform-basics.md
|
||||||
|
- Как работает провайдер (отличия от Terraform): 30_registry/guides/provider-behavior.md
|
||||||
- Структура манифестов: 30_registry/guides/terraform-structure.md
|
- Структура манифестов: 30_registry/guides/terraform-structure.md
|
||||||
- Глоссарий: 30_registry/guides/glossary.md
|
- Глоссарий: 30_registry/guides/glossary.md
|
||||||
- Проверенные примеры:
|
- Проверенные примеры:
|
||||||
- PostgreSQL: curated/postgres/pg_user_db.md
|
- PostgreSQL: curated/postgres/pg_user_db.md
|
||||||
- Пайплайн vDC → Edge → IP → SNAT: curated/pipeline/vdc_edge_ip_snat.md
|
- Пайплайн vDC → Edge → IP → SNAT → Штурвал: curated/pipeline/vdc_edge_ip_snat.md
|
||||||
- Ресурсы-модификаторы (IP организации, SNAT): curated/modifiers/org_ip_and_snat.md
|
- Ресурсы-модификаторы (IP организации, SNAT): curated/modifiers/org_ip_and_snat.md
|
||||||
|
|||||||
Reference in New Issue
Block a user