feat: add switch stack port config with dynamic serial resolution

- Add data source meraki_switch_stacks to resolve member serials by stack name
- Add switch_stack_port_configs variable: specify stack_name + port_range
  instead of individual switch serials
- Terraform applies port_range to ALL members of the stack automatically
- Merge switch_port_configs and switch_stack_port_configs into all_ports local
- Add example for bcn01-lab-stack01 (2x48p) in switch.auto.tfvars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Martinez
2026-03-25 08:42:48 +01:00
co-authored by Claude Sonnet 4.6
parent 16c09f8cc5
commit c6343d977e
5 changed files with 126 additions and 13 deletions
+54 -11
View File
@@ -16,21 +16,39 @@ data "meraki_networks" "net" {
organization_id = data.meraki_organization.org.id
}
# Stacks de switches en la red (para resolución dinámica de seriales por nombre)
data "meraki_switch_stacks" "stacks" {
network_id = local.network_id
}
# Local para extraer el network_id exacto de la lista de redes
locals {
network_id = [for n in data.meraki_networks.net.items : n.id if n.name == var.network_name][0]
# Expande rangos de puertos: "1-24" -> ["1","2",...,"24"], "1" -> ["1"]
# Helper: expande un port_range en lista de port_ids
# "1-48" -> ["1","2",...,"48"] | "1" -> ["1"]
_expand_range = {
for config in concat(var.switch_port_configs, var.switch_stack_port_configs) :
"${try(config.serial, config.stack_name)}:${config.port_range}" => (
length(split("-", config.port_range)) == 2
? [for i in range(
tonumber(split("-", config.port_range)[0]),
tonumber(split("-", config.port_range)[1]) + 1
) : tostring(i)]
: [config.port_range]
)
}
# Mapa de nombre de stack -> lista de seriales de sus miembros
stack_serials = {
for stack in data.meraki_switch_stacks.stacks.items :
stack.name => stack.serials
}
# Expande switch_port_configs (serial explícito) en entradas individuales
switch_ports_expanded = flatten([
for config in var.switch_port_configs : [
for port_id in (
length(split("-", config.port_range)) == 2
? [for i in range(
tonumber(split("-", config.port_range)[0]),
tonumber(split("-", config.port_range)[1]) + 1
) : tostring(i)]
: [config.port_range]
) : {
for port_id in local._expand_range["${config.serial}:${config.port_range}"] : {
key = "${config.serial}:${port_id}"
serial = config.serial
port_id = port_id
@@ -42,6 +60,31 @@ locals {
}
]
])
# Expande switch_stack_port_configs (por nombre de stack) en entradas individuales
# Aplica el mismo port_range a TODOS los miembros del stack
stack_ports_expanded = flatten([
for config in var.switch_stack_port_configs : [
for serial in local.stack_serials[config.stack_name] : [
for port_id in local._expand_range["${config.stack_name}:${config.port_range}"] : {
key = "${serial}:${port_id}"
serial = serial
port_id = port_id
name = config.name
type = config.type
vlan = config.vlan
access_policy_type = config.access_policy_type
access_policy_number = config.access_policy_number
}
]
]
])
# Unión de ambas listas para el resource meraki_switch_port
all_ports = merge(
{ for p in local.switch_ports_expanded : p.key => p },
{ for p in local.stack_ports_expanded : p.key => p }
)
}
# --- CONFIGURACIÓN GATEWAY (MX) ---
@@ -122,9 +165,9 @@ resource "meraki_switch_access_policy" "dot1x" {
}
# 6. Configuración de puertos de switch
# port_range soporta rango "1-24" o puerto único "1"
# switch_port_configs: serial explícito | switch_stack_port_configs: por nombre de stack
resource "meraki_switch_port" "ports" {
for_each = { for p in local.switch_ports_expanded : p.key => p }
for_each = local.all_ports
depends_on = [meraki_switch_access_policy.dot1x]
serial = each.value.serial