From 11d05b03ed6b5a1869b73a5f2e561cec58def538 Mon Sep 17 00:00:00 2001 From: grodionov Date: Fri, 6 Feb 2026 14:35:56 +0300 Subject: [PATCH] =?UTF-8?q?doc:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BF=D0=BE=20alb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 29 ++++++-- alb/.gitignore | 7 ++ alb/README.md | 31 ++++++++ alb/albpool.tf | 120 ++++++++++++++++++++++++++++++ alb/local.tf | 45 +++++++++++ alb/outputs.tf | 14 ++++ alb/provider.tf | 33 ++++++++ alb/templates/cloudinit.yaml | 20 +++++ alb/terraform.tfvars | 71 ++++++++++++++++++ alb/tools.tf | 5 ++ alb/vapp.tf | 17 +++++ alb/var.tf | 59 +++++++++++++++ alb/vm.tf | 70 +++++++++++++++++ simpleVm/templates/cloudinit.yaml | 5 +- simpleVm/terraform.tfvars | 9 +-- 15 files changed, 522 insertions(+), 13 deletions(-) create mode 100644 alb/.gitignore create mode 100644 alb/README.md create mode 100644 alb/albpool.tf create mode 100644 alb/local.tf create mode 100644 alb/outputs.tf create mode 100644 alb/provider.tf create mode 100644 alb/templates/cloudinit.yaml create mode 100644 alb/terraform.tfvars create mode 100644 alb/tools.tf create mode 100644 alb/vapp.tf create mode 100644 alb/var.tf create mode 100644 alb/vm.tf diff --git a/README.md b/README.md index 7cdfbec..88f4184 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,30 @@ -# vm.dev.nubes.ru +# tfTemplate — инфраструктура в VMware Cloud Director (OpenTofu) Развёртывание ВМ в VMware Cloud Director (OpenTofu). ---- +## Внутренняя структура репозитория -**Нужно поднять простую ВМ?** — см. [simpleVm/README.md](simpleVm/README.md). +``` +tfTemplate/ +├── simpleVm/ # Модуль для развёртывания простой виртуальной машины +│ └── README.md # Документация по использованию simpleVm +├── alb/ # Модуль для создания Application Load Balancer (ALB) +│ ├── README.md # Документация по ALB +│ ├── terraform.tfvars # Пример параметров для ALB и подключения к облаку +│ └── albpool.tf # Логика работы ALB, примеры ресурса и firewall +├── README.md # Основная документация (этот файл) +└── ... # Прочие модули, файлы и переменные +``` + +- **simpleVm/** — развёртывание одиночных виртуальных машин. +- **alb/** — конфигурация балансировщиков нагрузки (ALB), сетевых профилей и firewall. +- **terraform.tfvars** — образец пользовательских переменных, включая настройку облака и ALB. +- **albpool.tf** — логика и правила балансировки и доступов. +- **README.md** — описание проекта, структура и ссылки на детали модулей. + +_Для детального описания каждого модуля смотрите соответствующие README внутри директорий._ + +- **Простая ВМ** — [simpleVm/README.md](simpleVm/README.md) +- **ALB (Load Balancer)** — [alb/README.md](alb/README.md) --- - -*Здесь со временем можно добавить ссылки на другие сценарии (например, несколько vDC, сложные конфигурации).* diff --git a/alb/.gitignore b/alb/.gitignore new file mode 100644 index 0000000..5808407 --- /dev/null +++ b/alb/.gitignore @@ -0,0 +1,7 @@ +.terraform/ +*.tfstate +*.tfstate.* +.terraform.lock.hcl +crash.*.log +# Секреты — лучше передавать через TF_VAR_* +# terraform.tfvars diff --git a/alb/README.md b/alb/README.md new file mode 100644 index 0000000..1ebd3df --- /dev/null +++ b/alb/README.md @@ -0,0 +1,31 @@ +# alb — балансировщик и опционально ВМ (OpenTofu) + +Создаётся NSX-T ALB в VMware Cloud Director: внешний IP (VIP), пулы по портам из `alb_ports`, Virtual Service. На Edge добавляется правило фаервола: входящий трафик на VIP разрешён (доступ к ВМ через балансировщик, например SSH на порт 22). + + +**Режимы backend'ов:** +- Если в `vcds` для vDC из `albConfiguration.vdc_key` заданы **`servers`** — создаются vApp и ВМ, затем пулы ALB получают их внутренние IP (сначала ВМ, потом балансировщик). +- Иначе backend'ы задаются списком **`albConfiguration.alb_backend_ips`** (внешние сервера; ВМ в конфиге не создаются). + +## Что нужно в vCD + +- Edge Gateway (имя → `albConfiguration.edge`) +- На Edge привязана Service Engine Group (`srv_engine_group`) +- IP Space (`vcd_ip_space`) +- Для создания ВМ: org-сеть `network_routed` в соответствующем vDC. + +## Запуск + +```bash +# Заполнить terraform.tfvars (или TF_VAR_*) +tofu init +tofu plan +tofu apply +``` + +После apply: будет выведен IP-адрес **`alb_vip`** — укажите его в DNS и используйте для внешнего доступа (Ingress). Подключение к сервисам ВМ осуществляется через балансировщик на соответствующих портах, например: +- HTTP: `http://:80` +- HTTPS: `https://:443` +- SSH (если настроено): `ssh deploy@` (при наличии порта 22 в `alb_ports`). +На Edge автоматически создаётся правило фаервола, разрешающее входящий трафик на этот VIP по заданным портам ALB. + diff --git a/alb/albpool.tf b/alb/albpool.tf new file mode 100644 index 0000000..78a4ff2 --- /dev/null +++ b/alb/albpool.tf @@ -0,0 +1,120 @@ +# ALB: на каждый порт из albConfiguration.alb_ports — пул и Virtual Service. Члены пулов — из ВМ или alb_backend_ips. + +data "vcd_vdc_group" "vdcGroup" { + count = local.is_vdc_group && var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + name = var.albConfiguration.vdcGroupName +} + +data "vcd_nsxt_edgegateway" "nsxt-edge" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + + org = var.vcds[var.albConfiguration.vdc_key].org + owner_id = local.is_vdc_group ? data.vcd_vdc_group.vdcGroup[0].id : null + vdc = local.is_vdc_group ? null : var.vcds[var.albConfiguration.vdc_key].vdc + name = var.albConfiguration.edge +} + +data "vcd_nsxt_alb_edgegateway_service_engine_group" "engine" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + org = var.vcds[var.albConfiguration.vdc_key].org + edge_gateway_id = data.vcd_nsxt_edgegateway.nsxt-edge[0].id + service_engine_group_name = var.albConfiguration.srv_engine_group +} + +data "vcd_ip_space" "ip_space" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + name = var.albConfiguration.vcd_ip_space +} + +data "vcd_org" "org_name" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + name = var.vcds[var.albConfiguration.vdc_key].org +} + +resource "vcd_ip_space_ip_allocation" "ip_ingress" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + + org_id = data.vcd_org.org_name[0].id + ip_space_id = data.vcd_ip_space.ip_space[0].id + type = "FLOATING_IP" +} + +resource "vcd_nsxt_alb_pool" "pool" { + for_each = var.albConfiguration.enabled ? toset([for p in var.albConfiguration.alb_ports : tostring(p)]) : toset([]) + provider = vcd.al[var.albConfiguration.vdc_key] + + org = var.vcds[var.albConfiguration.vdc_key].org + edge_gateway_id = data.vcd_nsxt_edgegateway.nsxt-edge[0].id + name = "${var.albConfiguration.alb_name}-${each.key}" + description = "Pool port ${each.key}" + algorithm = "ROUND_ROBIN" + default_port = tonumber(each.key) + + dynamic "member" { + for_each = local.backend_ips_for_alb + content { + ip_address = member.value + } + } + + depends_on = [vcd_vapp_vm.vm] +} + +resource "vcd_nsxt_alb_virtual_service" "vs" { + for_each = var.albConfiguration.enabled ? toset([for p in var.albConfiguration.alb_ports : tostring(p)]) : toset([]) + provider = vcd.al[var.albConfiguration.vdc_key] + + org = var.vcds[var.albConfiguration.vdc_key].org + name = "${var.albConfiguration.alb_name}-${each.key}" + edge_gateway_id = data.vcd_nsxt_edgegateway.nsxt-edge[0].id + pool_id = vcd_nsxt_alb_pool.pool[each.key].id + service_engine_group_id = data.vcd_nsxt_alb_edgegateway_service_engine_group.engine[0].service_engine_group_id + virtual_ip_address = vcd_ip_space_ip_allocation.ip_ingress[0].ip + application_profile_type = "L4" + + service_port { + start_port = tonumber(each.key) + type = "TCP_PROXY" + } +} + +# ------------------------------------------------------------------------------ +# Firewall: разрешаем входящий трафик на VIP балансировщика (доступ к ВМ через ALB). +# Внимание: vcd_nsxt_firewall управляет всеми пользовательскими правилами на Edge — +# при наличии других правил добавьте их в блок rule[] ниже. +# ------------------------------------------------------------------------------ +resource "vcd_nsxt_ip_set" "alb_vip" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + + name = "${var.albConfiguration.alb_name}-vip" + description = "ALB VIP for firewall rule" + edge_gateway_id = data.vcd_nsxt_edgegateway.nsxt-edge[0].id + ip_addresses = [vcd_ip_space_ip_allocation.ip_ingress[0].ip] +} + +resource "vcd_nsxt_firewall" "alb_access" { + count = var.albConfiguration.enabled ? 1 : 0 + provider = vcd.al[var.albConfiguration.vdc_key] + + org = var.vcds[var.albConfiguration.vdc_key].org + edge_gateway_id = data.vcd_nsxt_edgegateway.nsxt-edge[0].id + + rule { + name = "${var.albConfiguration.alb_name}-allow-inbound" + direction = "IN" + ip_protocol = "IPV4" + action = "ALLOW" + enabled = true + logging = false + destination_ids = [vcd_nsxt_ip_set.alb_vip[0].id] + # source_ids пусто = любой источник (подключение с любого IP к VIP) + # app_port_profile_ids пусто = любые порты (ограничение по портам задаётся ALB) + } +} diff --git a/alb/local.tf b/alb/local.tf new file mode 100644 index 0000000..f5ea60c --- /dev/null +++ b/alb/local.tf @@ -0,0 +1,45 @@ +locals { + is_vdc_group = lookup(var.albConfiguration, "edgeScope", "vdc") == "vdcGroup" + + # Список ВМ для создания: ключ = "${server_name}.${server_group}", только из vDC с заданными servers + servers = merge([ + for vcd_key, vcd_config in var.vcds : + try(length(vcd_config.servers), 0) > 0 ? merge([ + for server_group, servers in vcd_config.servers : + { + for server_name, server_config in servers : + "${server_name}.${server_group}" => { + vcd_key = vcd_key + server_group = server_group + server_name = server_name + config = server_config + network_routed = vcd_config.network_routed + } + } + ]...) : {} + ]...) + + # Доп. диски ВМ (dataDisk) + disks = merge([ + for server_name, server_config in local.servers : + { + for disk_uid, disk_size in try(server_config.config.dataDisk, {}) : + "${server_name}-${disk_uid}" => { + vcd_key = server_config.vcd_key + vm_name = server_name + unit_num = disk_uid + disk_size = disk_size + } + } + ]...) + + admin_password = var.admin_password != "" ? var.admin_password : random_password.admin_pass.result + + # Backend'ы для ALB: если в vdc_key есть создаваемые ВМ — их IP, иначе albConfiguration.alb_backend_ips + have_alb_vdc_servers = length([for k, v in local.servers : 1 if v.vcd_key == var.albConfiguration.vdc_key]) > 0 + alb_backend_ips_from_vms = local.have_alb_vdc_servers ? [ + for k, v in local.servers : vcd_vapp_vm.vm[k].network[0].ip + if v.vcd_key == var.albConfiguration.vdc_key + ] : [] + backend_ips_for_alb = length(local.alb_backend_ips_from_vms) > 0 ? local.alb_backend_ips_from_vms : var.albConfiguration.alb_backend_ips +} diff --git a/alb/outputs.tf b/alb/outputs.tf new file mode 100644 index 0000000..7984342 --- /dev/null +++ b/alb/outputs.tf @@ -0,0 +1,14 @@ +output "alb_vip" { + description = "Выделенный внешний IP балансировщика (указать в DNS и в Ingress)" + value = var.albConfiguration.enabled ? vcd_ip_space_ip_allocation.ip_ingress[0].ip : null +} + +output "alb_backend_ips" { + description = "IP backend'ов пулов ALB (из созданных ВМ или из albConfiguration.alb_backend_ips)" + value = var.albConfiguration.enabled ? local.backend_ips_for_alb : null +} + +output "vm_ips" { + description = "Имена и внутренние IP созданных ВМ (если заданы servers в vcds)" + value = length(local.servers) > 0 ? { for k, v in local.servers : k => vcd_vapp_vm.vm[k].network[0].ip } : {} +} diff --git a/alb/provider.tf b/alb/provider.tf new file mode 100644 index 0000000..2b31551 --- /dev/null +++ b/alb/provider.tf @@ -0,0 +1,33 @@ +# ALB и опционально ВМ. Backend'ы — albConfiguration.alb_backend_ips или из созданных ВМ. + +terraform { + required_providers { + vcd = { + source = "vmware/vcd" + version = "~> 3.14" + } + random = { + source = "hashicorp/random" + version = "~> 3.0" + } + } + # backend — при необходимости раскомментируйте и укажите свой + # backend "http" { + # address = "https://..." + # lock_address = "https://..." + # unlock_address = "https://..." + # } +} + +provider "vcd" { + alias = "al" + for_each = var.vcds + + user = var.vmware_username + password = var.vmware_password + org = each.value.org + vdc = each.value.vdc + url = each.value.url + max_retry_timeout = "10" + allow_unverified_ssl = true +} diff --git a/alb/templates/cloudinit.yaml b/alb/templates/cloudinit.yaml new file mode 100644 index 0000000..943a79d --- /dev/null +++ b/alb/templates/cloudinit.yaml @@ -0,0 +1,20 @@ +#cloud-config +hostname: ${hostname} +package_update: true +package_upgrade: false +packages: + - atop + +users: + - name: ${username} + sudo: "ALL=(ALL) NOPASSWD:ALL" + groups: "sudo" + shell: /bin/bash + ssh_authorized_keys: +%{ if length(ssh_authorized_keys) > 0 ~} +%{ for key in ssh_authorized_keys ~} + - ${key} +%{ endfor ~} +%{ else ~} + [] +%{ endif ~} diff --git a/alb/terraform.tfvars b/alb/terraform.tfvars new file mode 100644 index 0000000..63bee1e --- /dev/null +++ b/alb/terraform.tfvars @@ -0,0 +1,71 @@ +# Учётные данные лучше не коммитить: TF_VAR_vmware_username=... TF_vmware_password=... tofu apply +# vmware_username = "" +# vmware_password = "" + +####################################################### + + +# vcds — список (map) определённых vDC с настройками для подключения +vcds = { + "main" = { + url = "https://sandbox.nubes.ru/api" # URL к VMware Cloud Director API + org = "dev" # название организации в VCD + vdc = "dev" # имя виртуального датацентра (vDC) + network_routed = "dev-mgmt-network" # основная сетевая инфраструктура (routed network) + servers = { # описание групп серверов в данном vDC + "testservers" = { # имя группы серверов (любое) + "test01" = { # имя/идентификатор первой машины + cpu = "1" # Количество vCPU для ВМ + memory = "1024" # Количество памяти (RAM), в мегабайтах + osDisk = "18000" # Размер основного (системного) диска, в мегабайтах + dataDisk = { # Дополнительные диски: "номер" = "размер_в_МБ" + "1" = "3000" + } + network = { # Настройки сети + mode = "auto" # Режим назначения IP (auto/manual) + ip = "" # Статический IP (если mode = manual), иначе "" для автоматического назначения + } + catalog_name = "dev" # имя каталога с шаблоном ВМ + template_name = "RockyLinux_9-16G-cloudinit" # название шаблона операционной системы + init_username = "deploy" # имя пользователя для входа по SSH + ssh_authorized_keys = [ # список публичных SSH-ключей для авторизации + "ssh-ed25519 ********" + ] + } + "test02" = { + cpu = "1" + memory = "1024" + osDisk = "18000" + dataDisk = { + "1" = "2000" + } + network = { + mode = "auto" + ip = "" + } + catalog_name = "dev" + template_name = "RockyLinux_9-16G-cloudinit" + init_username = "deploy" + ssh_authorized_keys = [ + "ssh-ed25519 ********", + "ssh-rsa ********" + ] + } + } + } + } +} + +# albConfiguration — параметры ALB (Load Balancer) +albConfiguration = { + enabled = true # включить ALB (true) или выключить (false) + vdc_key = "main" # ключ vDC из vcds + edge = "dev" # имя Edge Gateway + edgeScope = "vdc" # область применения Edge: "vdc" или "vdcGroup" + vdcGroupName = "" # имя vdcGroup (если используется vdcGroup) + srv_engine_group = "SEGROUP-SANDBOX-CL1-SHARED-01" # имя группы Service Engine для ALB + vcd_ip_space = "internet-ipv4-v1" # название IP Space для ALB + alb_name = "my-lb-dev" # префикс имён VS и пулов + alb_ports = [80, 443] # список портов для ALB (один пул на порт) + alb_backend_ips = [] # IP backend'ов, [] — получить автоматически из servers +} \ No newline at end of file diff --git a/alb/tools.tf b/alb/tools.tf new file mode 100644 index 0000000..b914947 --- /dev/null +++ b/alb/tools.tf @@ -0,0 +1,5 @@ +# Пароль администратора ВМ (если не задан в переменной) +resource "random_password" "admin_pass" { + length = 20 + special = false +} diff --git a/alb/vapp.tf b/alb/vapp.tf new file mode 100644 index 0000000..e1b97ab --- /dev/null +++ b/alb/vapp.tf @@ -0,0 +1,17 @@ +# vApp и сеть — только для vDC, в которых заданы servers (создаём ВМ) +resource "vcd_vapp" "vapp" { + for_each = { for k, v in var.vcds : k => v if try(length(v.servers), 0) > 0 } + + provider = vcd.al[each.key] + name = each.key + power_on = false +} + +resource "vcd_vapp_org_network" "routed_network" { + for_each = vcd_vapp.vapp + + provider = vcd.al[each.key] + vapp_name = each.value.name + org_network_name = var.vcds[each.key].network_routed + reboot_vapp_on_removal = true +} diff --git a/alb/var.tf b/alb/var.tf new file mode 100644 index 0000000..e1da61d --- /dev/null +++ b/alb/var.tf @@ -0,0 +1,59 @@ +#################################################### +variable "vmware_username" { + type = string + default = "" +} + +variable "vmware_password" { + type = string + default = "" + sensitive = true +} + +#################################################### +# Пароль администратора ВМ (если пустой — генерируется в tools.tf) +variable "admin_password" { + type = string + default = "" +} + +#################################################### +# vDC: url, org, vdc — обязательно. network_routed и servers — для создания ВМ (backend'ов ALB). +variable "vcds" { + type = map(object({ + url = string + org = string + vdc = string + network_routed = optional(string) + servers = optional(map(map(object({ + cpu = string + memory = string + osDisk = string + catalog_name = string + template_name = string + dataDisk = optional(map(string), {}) + network = object({ + mode = string + ip = string + }) + init_username = optional(string) + ssh_authorized_keys = optional(list(string), []) + }))), {}) + })) +} + +#################################################### +variable "albConfiguration" { + type = object({ + enabled = bool + vdc_key = string # ключ из var.vcds + edge = string # имя Edge Gateway в vCD + edgeScope = string # "vdc" или "vdcGroup" + vdcGroupName = string # при edgeScope = "vdcGroup" + srv_engine_group = string # имя Service Engine Group на Edge + vcd_ip_space = string # имя IP Space для выделения внешнего IP + alb_name = string # префикс имён пулов и Virtual Service в vCD + alb_ports = list(number) # порты для проброса (один пул и один VS на порт) + alb_backend_ips = optional(list(string), []) # IP backend'ов; пустой — из созданных ВМ при наличии servers в vcds + }) +} diff --git a/alb/vm.tf b/alb/vm.tf new file mode 100644 index 0000000..08c1e7f --- /dev/null +++ b/alb/vm.tf @@ -0,0 +1,70 @@ +# ВМ — создаются только при наличии servers в var.vcds. Пулы ALB зависят от этих ВМ (backend = их IP). +resource "vcd_vapp_vm" "vm" { + for_each = local.servers + + provider = vcd.al[each.value.vcd_key] + vapp_name = vcd_vapp.vapp[each.value.vcd_key].name + name = each.key + computer_name = each.key + catalog_name = each.value.config.catalog_name + template_name = each.value.config.template_name + memory = each.value.config.memory + cpus = each.value.config.cpu + + network { + type = "org" + name = each.value.network_routed + ip_allocation_mode = lookup(each.value.config.network, "mode", "auto") == "manual" ? "MANUAL" : "POOL" + is_primary = true + ip = lookup(each.value.config.network, "mode", "auto") == "manual" ? lookup(each.value.config.network, "ip", null) : null + } + + override_template_disk { + bus_type = "paravirtual" + size_in_mb = each.value.config.osDisk + bus_number = 0 + unit_number = 0 + } + + customization { + enabled = true + force = false + allow_local_admin_password = true + auto_generate_password = false + admin_password = local.admin_password + } + + set_extra_config { + key = "disk.EnableUUID" + value = "TRUE" + } + + guest_properties = { + "user-data" = base64encode(templatefile("${path.module}/templates/cloudinit.yaml", { + hostname = each.key + username = lookup(each.value.config, "init_username", "deploy") + ssh_authorized_keys = lookup(each.value.config, "ssh_authorized_keys", []) + })) + } + + lifecycle { + ignore_changes = [disk] + } + + depends_on = [vcd_vapp_org_network.routed_network] +} + +resource "vcd_vm_internal_disk" "vmdisk" { + for_each = local.disks + + provider = vcd.al[each.value.vcd_key] + vapp_name = vcd_vapp.vapp[each.value.vcd_key].name + vm_name = each.value.vm_name + bus_type = "paravirtual" + bus_number = 0 + unit_number = each.value.unit_num + size_in_mb = each.value.disk_size + allow_vm_reboot = true + + depends_on = [vcd_vapp_vm.vm] +} diff --git a/simpleVm/templates/cloudinit.yaml b/simpleVm/templates/cloudinit.yaml index 9c469e6..c6544df 100644 --- a/simpleVm/templates/cloudinit.yaml +++ b/simpleVm/templates/cloudinit.yaml @@ -3,9 +3,8 @@ hostname: ${hostname} package_update: true package_upgrade: false packages: - - curl - - git - - jq + - atop + users: - name: ${username} diff --git a/simpleVm/terraform.tfvars b/simpleVm/terraform.tfvars index e790195..e63fb95 100644 --- a/simpleVm/terraform.tfvars +++ b/simpleVm/terraform.tfvars @@ -8,7 +8,7 @@ vcds = { "test" = { - url = "https://ngcloud.ru/api" + url = "https://sandbox.nubes.ru/api" org = "dev" vdc = "dev" network_routed = "dev-mgmt-network" @@ -19,18 +19,17 @@ vcds = { memory = "1024" osDisk = "35000" dataDisk = { - "1" = "10000" - "2" = "5480" + "1" = "6000" } network = { mode = "auto" ip = "" } catalog_name = "dev" - template_name = "Ubuntu_24-20G" + template_name = "Ubuntu_24-8G" init_username = "deploy" ssh_authorized_keys = [ - "ssh-ed25519 *********" + "ssh-ed25519 *******" ] } }