# ============================================================================= # 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 }