From 4a2eeb6c17b6c559089665ddb07d13d7a20ef10f Mon Sep 17 00:00:00 2001 From: Jose Martinez Date: Thu, 26 Mar 2026 20:59:20 +0100 Subject: [PATCH] feat: add Warm Spare (HA) with VIP for MX appliances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configura meraki_appliance_warm_spare con VIP flotante en WAN1: - Spare: BCN01-F04-MX02 (serial resuelto por nombre) - Uplink mode: virtual - VIP WAN1: 213.229.159.148 La IP de salida del tráfico será siempre la VIP (.148), independientemente de qué MX esté activo. Co-Authored-By: Claude Sonnet 4.6 --- modules/meraki-site/main.tf | 11 +++++++++++ modules/meraki-site/variables.tf | 12 ++++++++++++ sites/BCN01-LAB/main.tf | 1 + sites/BCN01-LAB/variables.tf | 11 +++++++++++ sites/BCN01-LAB/wan.auto.tfvars | 14 ++++++++++++-- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/meraki-site/main.tf b/modules/meraki-site/main.tf index ce7a121..e8962cf 100755 --- a/modules/meraki-site/main.tf +++ b/modules/meraki-site/main.tf @@ -200,6 +200,17 @@ resource "meraki_device_management_interface" "mx_wan" { wan1_static_dns = each.value.wan1_static_dns } +# 4c. Warm Spare (HA) — VIP flotante entre primary y spare +resource "meraki_appliance_warm_spare" "ha" { + count = var.mx_warm_spare != null ? 1 : 0 + + network_id = local.network_id + enabled = var.mx_warm_spare.enabled + spare_serial = local.device_serials[var.mx_warm_spare.spare_name] + uplink_mode = var.mx_warm_spare.uplink_mode + virtual_ip1 = var.mx_warm_spare.virtual_ip1 +} + # --- CONFIGURACIÓN SWITCHES (MS) --- # 5. Políticas de acceso 802.1X diff --git a/modules/meraki-site/variables.tf b/modules/meraki-site/variables.tf index e4a2489..38754a0 100755 --- a/modules/meraki-site/variables.tf +++ b/modules/meraki-site/variables.tf @@ -198,6 +198,18 @@ variable "mx_wan_uplinks" { description = "Configuración de interfaz WAN1 estática para cada MX. El serial se resuelve automáticamente por nombre de dispositivo." } +# Warm Spare (HA) del firewall MX +variable "mx_warm_spare" { + type = object({ + enabled = optional(bool, true) + spare_name = string # Nombre del MX spare en el Dashboard + uplink_mode = optional(string, "virtual") + virtual_ip1 = optional(string, null) # VIP WAN1 + }) + default = null + description = "Configuración Warm Spare (HA) del MX. El serial del spare se resuelve por nombre." +} + # Puertos del firewall MX variable "appliance_ports" { type = list(object({ diff --git a/sites/BCN01-LAB/main.tf b/sites/BCN01-LAB/main.tf index 158389f..c93df61 100755 --- a/sites/BCN01-LAB/main.tf +++ b/sites/BCN01-LAB/main.tf @@ -37,5 +37,6 @@ module "bcn01_lab" { stack_routing_interfaces = var.stack_routing_interfaces appliance_ports = var.appliance_ports mx_wan_uplinks = var.mx_wan_uplinks + mx_warm_spare = var.mx_warm_spare wifi_password_psk = var.wifi_password_psk } diff --git a/sites/BCN01-LAB/variables.tf b/sites/BCN01-LAB/variables.tf index 965f785..81450bd 100755 --- a/sites/BCN01-LAB/variables.tf +++ b/sites/BCN01-LAB/variables.tf @@ -184,6 +184,17 @@ variable "appliance_ports" { description = "Configuración de puertos LAN del firewall MX." } +variable "mx_warm_spare" { + type = object({ + enabled = optional(bool, true) + spare_name = string + uplink_mode = optional(string, "virtual") + virtual_ip1 = optional(string, null) + }) + default = null + description = "Configuración Warm Spare (HA) del MX." +} + variable "mx_wan_uplinks" { type = list(object({ name = string # Nombre del dispositivo en el Dashboard diff --git a/sites/BCN01-LAB/wan.auto.tfvars b/sites/BCN01-LAB/wan.auto.tfvars index 6af2d8b..71e1e1d 100644 --- a/sites/BCN01-LAB/wan.auto.tfvars +++ b/sites/BCN01-LAB/wan.auto.tfvars @@ -1,10 +1,20 @@ # Configuración WAN1 estática de los firewalls MX # El nombre debe coincidir exactamente con el nombre del dispositivo en el Dashboard # Dashboard > Security & SD-WAN > Appliance > nombre del dispositivo + +# Warm Spare (HA): VIP flotante entre primary y spare +# La IP de salida del tráfico será siempre la VIP +mx_warm_spare = { + enabled = true + spare_name = "BCN01-F04-MX02" + uplink_mode = "virtual" + virtual_ip1 = "213.229.159.148" # VIP WAN1 +} + mx_wan_uplinks = [ { # MX Primary - name = "eqt-lab-fw01-mx01" # TODO: ajustar al nombre real en el Dashboard + name = "BCN01-F04-MX01" # TODO: ajustar al nombre real en el Dashboard interfaces_wan1_enabled = true wan1_static_ip = "213.229.159.145" wan1_static_subnet_mask = "255.255.255.240" # /28 @@ -13,7 +23,7 @@ mx_wan_uplinks = [ }, { # MX Spare (Warm Spare / HA) - name = "eqt-lab-fw01-mx02" # TODO: ajustar al nombre real en el Dashboard + name = "BCN01-F04-MX02" # TODO: ajustar al nombre real en el Dashboard interfaces_wan1_enabled = true wan1_static_ip = "213.229.159.146" wan1_static_subnet_mask = "255.255.255.240" # /28