feat(fullpipe_chain): vApp и ВМ в цепочке — самодостаточный vm.tf (переменные+ресурсы+выводы), квота IP 4 и vCPU 12 (запас под кластер), README и tfvars-шаблон
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# vDC → Edge → внешние IP → SNAT → Штурвал
|
# vDC → Edge → внешние IP → SNAT → vApp → ВМ → Штурвал
|
||||||
|
|
||||||
Пример поднимает всю цепочку в Nubes:
|
Пример поднимает всю цепочку в Nubes:
|
||||||
|
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
- сетевой шлюз периметра (Edge) с балансировщиком AVI;
|
- сетевой шлюз периметра (Edge) с балансировщиком AVI;
|
||||||
- внешние IP на организации;
|
- внешние IP на организации;
|
||||||
- SNAT на шлюзе;
|
- SNAT на шлюзе;
|
||||||
|
- виртуальный каталог (vApp) и виртуальную машину (ВМ) внутри него — с доступом по SSH;
|
||||||
- Kubernetes-кластер Штурвал (сервис 150) на этой сети.
|
- Kubernetes-кластер Штурвал (сервис 150) на этой сети.
|
||||||
|
|
||||||
Организацию создайте заранее в ЛК: Terraform её не создаёт и не удаляет.
|
Организацию создайте заранее в ЛК: Terraform её не создаёт и не удаляет.
|
||||||
@@ -32,6 +33,7 @@ cd tf_examples/fullpipe_chain
|
|||||||
| `vdc_provider_vdc` | ЛК → создание vDC → «Provider VDC» | `Intel Broadwell 2.4` |
|
| `vdc_provider_vdc` | ЛК → создание vDC → «Provider VDC» | `Intel Broadwell 2.4` |
|
||||||
| `vdc_storage_config` | ЛК → создание vDC → доступные дисковые политики | `SATA` |
|
| `vdc_storage_config` | ЛК → создание vDC → доступные дисковые политики | `SATA` |
|
||||||
| `ip_space_name` | ЛК → карточка организации → внешние IP | `internet-ipv4-v1` |
|
| `ip_space_name` | ЛК → карточка организации → внешние IP | `internet-ipv4-v1` |
|
||||||
|
| `vm_user_public_key` | содержимое `~/.ssh/id_ed25519.pub` (`ssh-keygen` создаст пару, если её нет) | `ssh-ed25519 AAAA...` |
|
||||||
|
|
||||||
Остальные значения уже подставлены в `terraform.tfvars.example` — меняйте, если нужно.
|
Остальные значения уже подставлены в `terraform.tfvars.example` — меняйте, если нужно.
|
||||||
|
|
||||||
@@ -48,7 +50,7 @@ nano terraform.tfvars # подставьте значения из шага
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
terraform init # один раз — скачает провайдер
|
terraform init # один раз — скачает провайдер
|
||||||
terraform plan # покажет, что будет создано (5 ресурсов), ничего не меняет
|
terraform plan # покажет, что будет создано (7 ресурсов: vDC, Edge, IP, SNAT, vApp, ВМ, Штурвал)
|
||||||
terraform apply # создаст (подтвердить: yes)
|
terraform apply # создаст (подтвердить: yes)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -58,9 +60,12 @@ terraform apply # создаст (подтвердить: yes)
|
|||||||
terraform output # UUID и имена созданных услуг
|
terraform output # UUID и имена созданных услуг
|
||||||
```
|
```
|
||||||
|
|
||||||
И в ЛК: появились vDC, Edge и кластер Штурвал, на организации выделены внешние IP,
|
И в ЛК: появились vDC, Edge, vApp с ВМ и кластер Штурвал, на организации выделены внешние IP,
|
||||||
на шлюзе включён SNAT. Повторный `terraform plan` должен показать `No changes`.
|
на шлюзе включён SNAT. Повторный `terraform plan` должен показать `No changes`.
|
||||||
|
|
||||||
|
Адрес ВМ — в `terraform output vm_state_flat` (поля `externalConnect` и `internalConnect`),
|
||||||
|
вход: `ssh <vm_user_login>@<externalConnect>`.
|
||||||
|
|
||||||
Кластер Штурвала создаётся десятки минут — провайдер ждёт его
|
Кластер Штурвала создаётся десятки минут — провайдер ждёт его
|
||||||
(`operation_timeout = "60m"`), а в ЛК он появится со статусом `running`.
|
(`operation_timeout = "60m"`), а в ЛК он появится со статусом `running`.
|
||||||
Адреса Kubernetes API и Ingress — в `terraform output shturval_state_params`
|
Адреса Kubernetes API и Ingress — в `terraform output shturval_state_params`
|
||||||
@@ -81,14 +86,16 @@ terraform destroy
|
|||||||
| Edge | не трогается: у эджа нет операции `suspend` | `keep_on_destroy = true` |
|
| Edge | не трогается: у эджа нет операции `suspend` | `keep_on_destroy = true` |
|
||||||
| SNAT | не выключается | `keep_on_destroy = true` |
|
| SNAT | не выключается | `keep_on_destroy = true` |
|
||||||
| Квота внешних IP | не меняется: адреса держит кластер | `keep_on_destroy = true` |
|
| Квота внешних IP | не меняется: адреса держит кластер | `keep_on_destroy = true` |
|
||||||
|
| vApp | `suspend`: выключаются все ВМ внутри каталога | `suspend_on_destroy = true` |
|
||||||
|
| ВМ | `suspend` | `suspend_on_destroy = true` |
|
||||||
|
|
||||||
Следующий `terraform apply` усыновит объекты по имени и разморозит кластер и vDC
|
Следующий `terraform apply` усыновит объекты по имени и разморозит кластер и vDC
|
||||||
(`adopt_existing_on_create = true` → `resume`).
|
(`adopt_existing_on_create = true` → `resume`).
|
||||||
**Организация не удаляется никогда.**
|
**Организация не удаляется никогда.**
|
||||||
|
|
||||||
Полное удаление — осознанно: выставьте `keep_on_destroy = false` и
|
Полное удаление — осознанно: выставьте `keep_on_destroy = false` и
|
||||||
`suspend_on_destroy = false`, порядок — кластер → `count = 0` → SNAT → Edge → vDC
|
`suspend_on_destroy = false`, порядок — кластер → ВМ → vApp → `count = 0` → SNAT → Edge → vDC
|
||||||
(vDC удаляется только через 14 дней после `suspend`).
|
(vApp и vDC удаляются только через 14 дней после `suspend`).
|
||||||
|
|
||||||
## Состав файлов
|
## Состав файлов
|
||||||
|
|
||||||
@@ -100,6 +107,7 @@ terraform destroy
|
|||||||
| `vdc.tf` | виртуальный датацентр |
|
| `vdc.tf` | виртуальный датацентр |
|
||||||
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
| `edge.tf` | сетевой шлюз периметра (Edge) |
|
||||||
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
| `modifiers.tf` | внешние IP на организации + SNAT на шлюзе |
|
||||||
|
| `vm.tf` | vApp и ВМ: переменные vApp/ВМ, оба ресурса и их выводы (удаляется целиком — остальное не затронуто) |
|
||||||
| `shturval.tf` | Kubernetes-кластер Штурвал: переменные Штурвала, группы воркеров и сам ресурс |
|
| `shturval.tf` | Kubernetes-кластер Штурвал: переменные Штурвала, группы воркеров и сам ресурс |
|
||||||
| `outputs.tf` | UUID и имена созданных услуг (vDC, Edge, Штурвал) |
|
| `outputs.tf` | UUID и имена созданных услуг (vDC, Edge, Штурвал) |
|
||||||
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
| `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) |
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ organization = "organ"
|
|||||||
|
|
||||||
# Имя ipSpace для внешнего IP. Смотреть в ЛК в карточке организации.
|
# Имя ipSpace для внешнего IP. Смотреть в ЛК в карточке организации.
|
||||||
ip_space_name = "internet-ipv4-v1"
|
ip_space_name = "internet-ipv4-v1"
|
||||||
# Сколько внешних IP выделить (строкой).
|
# Сколько внешних IP выделить (строкой): 3 держит кластер Штурвал, 4-й — внешний адрес ВМ.
|
||||||
ip_count = "3"
|
ip_count = "4"
|
||||||
|
|
||||||
# --- vDC (виртуальный датацентр) ---
|
# --- vDC (виртуальный датацентр) ---
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@ vdc_resource_name = "fullpipe-vdc"
|
|||||||
vdc_network_provider = "snb1"
|
vdc_network_provider = "snb1"
|
||||||
# ЛК → создание vDC → «Provider VDC»
|
# ЛК → создание vDC → «Provider VDC»
|
||||||
vdc_provider_vdc = "Intel Broadwell 2.4"
|
vdc_provider_vdc = "Intel Broadwell 2.4"
|
||||||
# vCPU, шт.
|
# vCPU, шт. Кластер Штурвал занимает 8 vCPU (2 ноды × 4), поэтому для ВМ нужен запас.
|
||||||
vdc_cpu_allocated = 8
|
vdc_cpu_allocated = 12
|
||||||
# Резервирование vCPU, %: допустимы 0, 50 или 80
|
# Резервирование vCPU, %: допустимы 0, 50 или 80
|
||||||
vdc_cpu_guaranteed = 0
|
vdc_cpu_guaranteed = 0
|
||||||
# RAM, ГБ
|
# RAM, ГБ
|
||||||
@@ -52,6 +52,27 @@ nsxt_ip_addr_pool = "10.10.102.0/24"
|
|||||||
nsxt_main_dns = "81.22.46.22"
|
nsxt_main_dns = "81.22.46.22"
|
||||||
nsxt_second_dns = "185.247.187.77"
|
nsxt_second_dns = "185.247.187.77"
|
||||||
|
|
||||||
|
# --- vApp и ВМ (всё лежит в vm.tf) ---
|
||||||
|
#
|
||||||
|
# У переменных vApp/ВМ есть рабочие значения по умолчанию. Обязательно задать
|
||||||
|
# только публичный SSH-ключ: возьмите его содержимое командой
|
||||||
|
# cat ~/.ssh/id_ed25519.pub
|
||||||
|
vm_user_public_key = "ssh-ed25519 AAAA... ваш публичный ключ"
|
||||||
|
|
||||||
|
# Остальное — по необходимости (раскомментируйте и поменяйте):
|
||||||
|
#
|
||||||
|
# vapp_resource_name = "fullpipe-vapp" # имя услуги vApp в ЛК
|
||||||
|
# vapp_name = "fullpipe-vapp-01" # имя vApp: маска ^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$,
|
||||||
|
# # уникально в организации, участвует в DNS-имени ВМ
|
||||||
|
# vm_resource_name = "fullpipe-vm-01" # имя услуги ВМ в ЛК
|
||||||
|
# vm_name = "web01" # имя ВМ: имя IP Set = {vapp_name}-{vm_name}
|
||||||
|
# vm_image = "Ubuntu_22-20G" # RockyLinux_9-16G-cloudinit | Ubuntu_22-20G | Debian_13-20G
|
||||||
|
# vm_cpu = 2 # vCPU, 1..64
|
||||||
|
# vm_ram = 2 # RAM, ГБ, 1..256
|
||||||
|
# vm_disk = 20 # дополнительный диск, ГБ
|
||||||
|
# vm_user_login = "ubuntu" # учётка SSH
|
||||||
|
# vm_same_snat = false # false — ВМ за общим SNAT шлюза
|
||||||
|
|
||||||
# --- Штурвал (Kubernetes-кластер, сервис 150) ---
|
# --- Штурвал (Kubernetes-кластер, сервис 150) ---
|
||||||
#
|
#
|
||||||
# Все настройки Штурвала лежат в shturval.tf, у каждой переменной есть рабочий
|
# Все настройки Штурвала лежат в shturval.tf, у каждой переменной есть рабочий
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ variable "ip_space_name" {
|
|||||||
|
|
||||||
variable "ip_count" {
|
variable "ip_count" {
|
||||||
type = string
|
type = string
|
||||||
default = "3"
|
default = "4"
|
||||||
description = "Сколько внешних IP выделить на организации. Строкой — так его отдаёт платформа."
|
description = "Сколько внешних IP выделить на организации: 3 держит кластер Штурвал (API, Ingress и запас) + 1 — внешний адрес ВМ. Строкой — так его отдаёт платформа."
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- vDC (виртуальный датацентр) ---
|
# --- vDC (виртуальный датацентр) ---
|
||||||
@@ -56,8 +56,8 @@ variable "vdc_provider_vdc" {
|
|||||||
|
|
||||||
variable "vdc_cpu_allocated" {
|
variable "vdc_cpu_allocated" {
|
||||||
type = number
|
type = number
|
||||||
default = 8
|
default = 12
|
||||||
description = "vCPU, шт."
|
description = "vCPU, шт. Кластер Штурвал при настройках по умолчанию занимает 8 vCPU (2 ноды × «TKG 4CPU 8RAM»), поэтому для ВМ нужен запас: 12 хватает на кластер и ВМ."
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "vdc_cpu_guaranteed" {
|
variable "vdc_cpu_guaranteed" {
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# vApp (услуга 26) и виртуальная машина (услуга 28)
|
||||||
|
#
|
||||||
|
# Всё, что относится к ВМ, лежит ТОЛЬКО в этом файле: переменные, их значения
|
||||||
|
# по умолчанию, оба ресурса и выводы. Чтобы выключить ВМ из цепочки — удалите
|
||||||
|
# или закомментируйте этот файл (по аналогии с shturval.tf).
|
||||||
|
#
|
||||||
|
# Место в цепочке:
|
||||||
|
# орга (вручную в ЛК) → vDC (21) → Edge (22) → внешние IP → SNAT
|
||||||
|
# → [ vApp (26) → ВМ (28) ] → Штурвал (150)
|
||||||
|
#
|
||||||
|
# Зависимости: vApp требует vdc_uid (21) и nsxt_uid (22); ВМ требует vapp_uid (26).
|
||||||
|
# Своей сети у vApp нет — ВМ получает адрес в routed-сети шлюза.
|
||||||
|
#
|
||||||
|
# Внешний доступ: ВМ публикуется за общим SNAT шлюза (same_snat = false), для
|
||||||
|
# этого ipSpace должен быть выделен на организации и включён как SNAT
|
||||||
|
# (см. modifiers.tf). Нужен отдельный внешний адрес — same_snat = true.
|
||||||
|
# ipSpace для ВМ берётся тот же, что у SNAT (var.ip_space_name).
|
||||||
|
#
|
||||||
|
# Режим destroy: у обеих услуг delete требует предварительного suspend,
|
||||||
|
# поэтому по умолчанию suspend_on_destroy = true («заморозка»).
|
||||||
|
# Полное удаление vApp возможно только через 14 дней после suspend.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# --- Переменные vApp ---
|
||||||
|
|
||||||
|
variable "vapp_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-vapp"
|
||||||
|
description = "Имя услуги «Виртуальный каталог ВМ (vApp)» в ЛК. Любое, удобное вам."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vapp_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-vapp-01"
|
||||||
|
description = "Имя vApp. Маска ^[a-z0-9][a-z0-9.-]{3,61}[a-z0-9]$, уникально в организации; участвует в DNS-имени ВМ. Не оставляйте значение по умолчанию платформы."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Переменные ВМ ---
|
||||||
|
|
||||||
|
variable "vm_resource_name" {
|
||||||
|
type = string
|
||||||
|
default = "fullpipe-vm-01"
|
||||||
|
description = "Имя услуги «Виртуальная машина» в ЛК."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_name" {
|
||||||
|
type = string
|
||||||
|
default = "web01"
|
||||||
|
description = "Имя ВМ. Маска ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$. Определяет имя IP Set: {vapp_name}-{vm_name}."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_image" {
|
||||||
|
type = string
|
||||||
|
default = "Ubuntu_22-20G"
|
||||||
|
description = "Образ ОС. Доступные значения: RockyLinux_9-16G-cloudinit, Ubuntu_22-20G, Debian_13-20G. После создания не меняется."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_cpu" {
|
||||||
|
type = number
|
||||||
|
default = 2
|
||||||
|
description = "vCPU (1..64), шт."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_ram" {
|
||||||
|
type = number
|
||||||
|
default = 2
|
||||||
|
description = "RAM (1..256), ГБ."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_disk" {
|
||||||
|
type = number
|
||||||
|
default = 20
|
||||||
|
description = "Дополнительный диск, ГБ: основной диск зависит от образа."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_user_login" {
|
||||||
|
type = string
|
||||||
|
default = "ubuntu"
|
||||||
|
description = "Учётка SSH на ВМ. После создания не меняется."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_user_public_key" {
|
||||||
|
type = string
|
||||||
|
description = "Публичный SSH-ключ в формате OpenSSH (содержимое ~/.ssh/id_ed25519.pub). После создания не меняется. Задаётся в terraform.tfvars."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_access_port_list" {
|
||||||
|
type = list(object({
|
||||||
|
port = string
|
||||||
|
type = string
|
||||||
|
}))
|
||||||
|
default = [
|
||||||
|
{ port = "22", type = "tcp" }
|
||||||
|
]
|
||||||
|
description = "Белый список портов для доступа к ВМ извне. type: tcp | udp | all."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_access_ip_list" {
|
||||||
|
type = list(string)
|
||||||
|
default = ["0.0.0.0/0"]
|
||||||
|
description = "Белый список адресов, которым разрешён доступ к ВМ. Требует выделенного внешнего IP."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_same_snat" {
|
||||||
|
type = bool
|
||||||
|
default = false
|
||||||
|
description = "false — ВМ публикуется за общим SNAT шлюза; true — за отдельным внешним IP услуги."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- vApp (услуга 26) ---
|
||||||
|
|
||||||
|
resource "nubes_vapp" "vapp" {
|
||||||
|
resource_name = var.vapp_resource_name
|
||||||
|
vapp_name = var.vapp_name
|
||||||
|
|
||||||
|
vdc_uid = nubes_vc_vdc.vdc.id # ссылка на vDC этого же конфига
|
||||||
|
nsxt_uid = nubes_vc_nsxt.edge.id # ссылка на Edge этого же конфига
|
||||||
|
|
||||||
|
# «Заморозка»: destroy переводит vApp в suspend (delete требует suspend).
|
||||||
|
suspend_on_destroy = true
|
||||||
|
|
||||||
|
# Повторный apply усыновит уже существующий vApp, а не упадёт с конфликтом имён.
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
|
||||||
|
# vApp требует готовую сеть: сначала ipSpace на организации и SNAT на шлюзе.
|
||||||
|
depends_on = [nubes_vc_nsxt_snat.snat]
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- ВМ (услуга 28) ---
|
||||||
|
|
||||||
|
resource "nubes_vc_vm_v3" "vm" {
|
||||||
|
resource_name = var.vm_resource_name
|
||||||
|
vm_name = var.vm_name
|
||||||
|
|
||||||
|
vapp_uid = nubes_vapp.vapp.id # ВМ размещается в vApp
|
||||||
|
image_vm = var.vm_image
|
||||||
|
|
||||||
|
vm_cpu = var.vm_cpu
|
||||||
|
vm_ram = var.vm_ram
|
||||||
|
vm_disk = var.vm_disk
|
||||||
|
|
||||||
|
user_login = var.vm_user_login
|
||||||
|
user_public_key = var.vm_user_public_key
|
||||||
|
|
||||||
|
# Внешний доступ — ipSpace тот же, что у SNAT шлюза.
|
||||||
|
ip_space_name = var.ip_space_name
|
||||||
|
same_snat = var.vm_same_snat
|
||||||
|
access_port_list = jsonencode(var.vm_access_port_list)
|
||||||
|
access_ip_list = jsonencode(var.vm_access_ip_list)
|
||||||
|
|
||||||
|
# «Заморозка»: destroy переводит ВМ в suspend.
|
||||||
|
suspend_on_destroy = true
|
||||||
|
|
||||||
|
adopt_existing_on_create = true
|
||||||
|
|
||||||
|
# ВМ создаётся и включается с customization (учётка + ключ) — это долго.
|
||||||
|
# Если операция не успевает, увеличьте таймаут.
|
||||||
|
operation_timeout = "15m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Выводы ---
|
||||||
|
|
||||||
|
output "vapp_id" {
|
||||||
|
description = "UUID созданного vApp (услуга 26)"
|
||||||
|
value = nubes_vapp.vapp.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vapp_name" {
|
||||||
|
description = "Имя vApp"
|
||||||
|
value = nubes_vapp.vapp.vapp_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vm_id" {
|
||||||
|
description = "UUID созданной ВМ (услуга 28)"
|
||||||
|
value = nubes_vc_vm_v3.vm.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vm_state_flat" {
|
||||||
|
description = "Параметры ВМ из API: externalConnect — внешний адрес, internalConnect — адрес в routed-сети, fqdn — DNS-имя"
|
||||||
|
value = nubes_vc_vm_v3.vm.state_out_flat
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user