diff --git a/TMP/backup_2026-09-25/fpipegmail/edge.tf b/TMP/backup_2026-09-25/fpipegmail/edge.tf new file mode 100644 index 0000000..ec8f962 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/edge.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fpipegmail/modifiers.tf b/TMP/backup_2026-09-25/fpipegmail/modifiers.tf new file mode 100644 index 0000000..a148873 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/modifiers.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fpipegmail/outputs.tf b/TMP/backup_2026-09-25/fpipegmail/outputs.tf new file mode 100644 index 0000000..13ee3e0 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/outputs.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fpipegmail/provider.tf b/TMP/backup_2026-09-25/fpipegmail/provider.tf new file mode 100644 index 0000000..9d91910 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/provider.tf @@ -0,0 +1,4 @@ +provider "nubes" { + api_token = var.api_token + api_endpoint = var.api_endpoint +} diff --git a/TMP/backup_2026-09-25/fpipegmail/shturval.tf b/TMP/backup_2026-09-25/fpipegmail/shturval.tf new file mode 100644 index 0000000..9c9cce4 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/shturval.tf @@ -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] +} diff --git a/TMP/backup_2026-09-25/fpipegmail/terraform.tfvars.example b/TMP/backup_2026-09-25/fpipegmail/terraform.tfvars.example new file mode 100644 index 0000000..a938d21 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/terraform.tfvars.example @@ -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\"}]" diff --git a/TMP/backup_2026-09-25/fpipegmail/variables.tf b/TMP/backup_2026-09-25/fpipegmail/variables.tf new file mode 100644 index 0000000..7e934d3 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/variables.tf @@ -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" +} diff --git a/TMP/backup_2026-09-25/fpipegmail/vdc.tf b/TMP/backup_2026-09-25/fpipegmail/vdc.tf new file mode 100644 index 0000000..f69039e --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/vdc.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fpipegmail/versions.tf b/TMP/backup_2026-09-25/fpipegmail/versions.tf new file mode 100644 index 0000000..eca54b9 --- /dev/null +++ b/TMP/backup_2026-09-25/fpipegmail/versions.tf @@ -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" + } + } +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/README.md b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/README.md new file mode 100644 index 0000000..6fa4910 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/README.md @@ -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. diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/edge.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/edge.tf new file mode 100644 index 0000000..4e22f03 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/edge.tf @@ -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 + } +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/modifiers.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/modifiers.tf new file mode 100644 index 0000000..6757f42 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/modifiers.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/outputs.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/outputs.tf new file mode 100644 index 0000000..d2fcf4b --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/outputs.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/provider.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/provider.tf new file mode 100644 index 0000000..3a523ae --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/provider.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/terraform.tfvars.example b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/terraform.tfvars.example new file mode 100644 index 0000000..4c6f6e0 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/terraform.tfvars.example @@ -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" diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/variables.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/variables.tf new file mode 100644 index 0000000..25bbb53 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/variables.tf @@ -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 для машин за шлюзом." +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/vdc.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/vdc.tf new file mode 100644 index 0000000..c5f366d --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/vdc.tf @@ -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 +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/versions.tf b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/versions.tf new file mode 100644 index 0000000..193f90d --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/fullpipe_chain/versions.tf @@ -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" + } + } +} diff --git a/TMP/backup_2026-09-25/fullpipe_example/pipeline/vdc_edge_ip_snat.md b/TMP/backup_2026-09-25/fullpipe_example/pipeline/vdc_edge_ip_snat.md new file mode 100644 index 0000000..af70999 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/pipeline/vdc_edge_ip_snat.md @@ -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). diff --git a/TMP/backup_2026-09-25/fullpipe_example/tf_examples_README.md b/TMP/backup_2026-09-25/fullpipe_example/tf_examples_README.md new file mode 100644 index 0000000..264dde0 --- /dev/null +++ b/TMP/backup_2026-09-25/fullpipe_example/tf_examples_README.md @@ -0,0 +1,32 @@ +# Примеры Terraform для Nubes + +> ## Внимание: рабочая папка одна +> +> Для работы используйте **только** [`fullpipe_chain`](fullpipe_chain/) — это пример +> «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`.