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:
co-authored by
Claude Sonnet 4.6
parent
16c09f8cc5
commit
c6343d977e
@@ -16,21 +16,39 @@ data "meraki_networks" "net" {
|
|||||||
organization_id = data.meraki_organization.org.id
|
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
|
# Local para extraer el network_id exacto de la lista de redes
|
||||||
locals {
|
locals {
|
||||||
network_id = [for n in data.meraki_networks.net.items : n.id if n.name == var.network_name][0]
|
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
|
||||||
switch_ports_expanded = flatten([
|
# "1-48" -> ["1","2",...,"48"] | "1" -> ["1"]
|
||||||
for config in var.switch_port_configs : [
|
_expand_range = {
|
||||||
for port_id in (
|
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
|
length(split("-", config.port_range)) == 2
|
||||||
? [for i in range(
|
? [for i in range(
|
||||||
tonumber(split("-", config.port_range)[0]),
|
tonumber(split("-", config.port_range)[0]),
|
||||||
tonumber(split("-", config.port_range)[1]) + 1
|
tonumber(split("-", config.port_range)[1]) + 1
|
||||||
) : tostring(i)]
|
) : tostring(i)]
|
||||||
: [config.port_range]
|
: [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 local._expand_range["${config.serial}:${config.port_range}"] : {
|
||||||
key = "${config.serial}:${port_id}"
|
key = "${config.serial}:${port_id}"
|
||||||
serial = config.serial
|
serial = config.serial
|
||||||
port_id = port_id
|
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) ---
|
# --- CONFIGURACIÓN GATEWAY (MX) ---
|
||||||
@@ -122,9 +165,9 @@ resource "meraki_switch_access_policy" "dot1x" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 6. Configuración de puertos de switch
|
# 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" {
|
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]
|
depends_on = [meraki_switch_access_policy.dot1x]
|
||||||
|
|
||||||
serial = each.value.serial
|
serial = each.value.serial
|
||||||
|
|||||||
@@ -119,3 +119,18 @@ variable "switch_port_configs" {
|
|||||||
description = "Puertos de switch a configurar. access_policy_number referencia el número de la política creada en switch_access_policies."
|
description = "Puertos de switch a configurar. access_policy_number referencia el número de la política creada en switch_access_policies."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Configuración de puertos por nombre de stack (resolución dinámica de seriales)
|
||||||
|
variable "switch_stack_port_configs" {
|
||||||
|
type = list(object({
|
||||||
|
stack_name = string # nombre exacto del stack en Meraki Dashboard
|
||||||
|
port_range = string # puerto único "1" o rango "1-48"
|
||||||
|
name = optional(string, "")
|
||||||
|
type = optional(string, "access")
|
||||||
|
vlan = optional(number, null)
|
||||||
|
access_policy_type = optional(string, "Open")
|
||||||
|
access_policy_number = optional(number, null)
|
||||||
|
}))
|
||||||
|
default = []
|
||||||
|
description = "Puertos de stack a configurar por nombre. Terraform resuelve los seriales de todos los miembros automáticamente."
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,4 +31,5 @@ module "bcn01_lab" {
|
|||||||
radius_secret = var.radius_secret
|
radius_secret = var.radius_secret
|
||||||
switch_access_policies = var.switch_access_policies
|
switch_access_policies = var.switch_access_policies
|
||||||
switch_port_configs = var.switch_port_configs
|
switch_port_configs = var.switch_port_configs
|
||||||
|
switch_stack_port_configs = var.switch_stack_port_configs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,3 +73,42 @@ switch_access_policies = [
|
|||||||
#
|
#
|
||||||
# ]
|
# ]
|
||||||
switch_port_configs = []
|
switch_port_configs = []
|
||||||
|
|
||||||
|
# --- PUERTOS DE STACK ---
|
||||||
|
# Terraform resuelve automáticamente los seriales de todos los miembros del stack.
|
||||||
|
# El stack_name debe coincidir exactamente con el nombre en Dashboard > Switches > Stacks.
|
||||||
|
# Terraform aplicará el mismo port_range a CADA switch del stack (ambos de 48 puertos).
|
||||||
|
#
|
||||||
|
# Ejemplo para bcn01-lab-stack01 (2x 48 puertos):
|
||||||
|
# switch_stack_port_configs = [
|
||||||
|
#
|
||||||
|
# # Puertos 1-44: acceso general con 802.1X (PCs, portátiles)
|
||||||
|
# {
|
||||||
|
# stack_name = "bcn01-lab-stack01"
|
||||||
|
# port_range = "1-44"
|
||||||
|
# type = "access"
|
||||||
|
# vlan = 100 # ACCESS - fallback si Okta no devuelve VLAN
|
||||||
|
# access_policy_type = "Custom access policy"
|
||||||
|
# access_policy_number = 1 # id de la política DOT1X-CORPO
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# # Puertos 45-46: impresoras (VLAN fija, sin 802.1X)
|
||||||
|
# {
|
||||||
|
# stack_name = "bcn01-lab-stack01"
|
||||||
|
# port_range = "45-46"
|
||||||
|
# type = "access"
|
||||||
|
# vlan = 103 # PRINTERS
|
||||||
|
# access_policy_type = "Open"
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# # Puertos 47-48: APs (VLAN fija, sin 802.1X)
|
||||||
|
# {
|
||||||
|
# stack_name = "bcn01-lab-stack01"
|
||||||
|
# port_range = "47-48"
|
||||||
|
# type = "access"
|
||||||
|
# vlan = 108 # APs
|
||||||
|
# access_policy_type = "Open"
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# ]
|
||||||
|
switch_stack_port_configs = []
|
||||||
|
|||||||
@@ -110,3 +110,18 @@ variable "switch_port_configs" {
|
|||||||
default = []
|
default = []
|
||||||
description = "Puertos de switch a configurar con 802.1X. Requiere serial del switch."
|
description = "Puertos de switch a configurar con 802.1X. Requiere serial del switch."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Configuración de puertos por nombre de stack
|
||||||
|
variable "switch_stack_port_configs" {
|
||||||
|
type = list(object({
|
||||||
|
stack_name = string
|
||||||
|
port_range = string
|
||||||
|
name = optional(string, "")
|
||||||
|
type = optional(string, "access")
|
||||||
|
vlan = optional(number, null)
|
||||||
|
access_policy_type = optional(string, "Open")
|
||||||
|
access_policy_number = optional(number, null)
|
||||||
|
}))
|
||||||
|
default = []
|
||||||
|
description = "Puertos de stack a configurar por nombre. Terraform resuelve los seriales automáticamente."
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user