feat: real flat+mgmt-VLAN topology in host_vars; role tweaks
host_vars: DATA VLAN 30 (ether1 uplink + ether2-7 + sfp1/2), isolated MGMT VLAN 99 on ether8, mgmt 192.168.88.1/24, no gateway, NTP disabled. Role: switch_ntp_enabled flag (enable/disable NTP), conditional default route (skip when no gateway), and a guarded removal of the legacy defconf bridge IP so the mgmt IP lives only on vlan-mgmt. Membership Jinja re-validated; lint+syntax clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8a42f5482f
commit
ebd21623ef
4 changed files with 55 additions and 24 deletions
|
|
@ -5,40 +5,46 @@
|
|||
# base MAC (ether1): D0:EA:11:24:F4:AA
|
||||
# RouterOS: 7.19.6 stable (bootloader already current) -> pinned target below
|
||||
#
|
||||
# Bootstrap status (2026-06-08): identity set; user `sjat` (full) created with the
|
||||
# operator ed25519 key imported + a vaulted password (vault_switch_admin_password in
|
||||
# group_vars/mikrotik.vault.yml). Key login verified. Default `admin` still enabled
|
||||
# (not yet hardened). Switch currently on the bench at 192.168.88.1 (defconf, not yet
|
||||
# reset/VLAN-configured). Real mgmt addressing below is the FUTURE production plan.
|
||||
# Topology (decided 2026-06-09, see docs/superpowers/specs/
|
||||
# 2026-06-09-crs310-flat-mgmtvlan-design.md): the switch is a FLAT L2 switch on the
|
||||
# makerspace 10.2.30.0/24 network with its management isolated on a dedicated VLAN.
|
||||
# - ether1 is the copper UPLINK (SFP+ deferred until connectors arrive).
|
||||
# - DATA VLAN 30: flat 10.2.30.0/24 bridged through; the switch does NO routing/DHCP
|
||||
# and the CPU is not a member (no switch presence on the user network).
|
||||
# - MGMT VLAN 99: isolated; switch mgmt IP 192.168.88.1/24 on vlan-mgmt, reachable
|
||||
# only from the dedicated mgmt port ether8. No gateway, no NTP/DNS (no internet).
|
||||
|
||||
# Day-2 connection: key auth as the named admin user (overrides the bootstrap
|
||||
# default ansible_user=admin in group_vars/mikrotik.yml).
|
||||
ansible_user: sjat
|
||||
|
||||
switch_identity_name: "crs310-maker"
|
||||
|
||||
# ----- Management (isolated VLAN 99) -----
|
||||
switch_mgmt_vlan_id: 99
|
||||
switch_mgmt_address: "10.0.99.2/24" # EDIT: real mgmt IP
|
||||
switch_mgmt_gateway: "10.0.99.1" # EDIT: real gateway
|
||||
switch_dns_servers: "10.0.99.1"
|
||||
switch_ntp_servers: "10.0.99.1"
|
||||
switch_mgmt_address: "192.168.88.1/24"
|
||||
switch_mgmt_gateway: "" # isolated mgmt -> no default route
|
||||
switch_dns_servers: "" # no DNS on an isolated mgmt plane
|
||||
switch_ntp_enabled: false # no internet on mgmt -> NTP would only error
|
||||
|
||||
switch_admin_user: "sjat"
|
||||
|
||||
# PLACEHOLDER VLAN/port topology — vlans.yml is correct mechanism, but these IDs
|
||||
# and the per-port map are NOT the real makerspace plan. Replace with the real
|
||||
# VLAN ids + full ether1-8/sfp map before any on-site VLAN run. Notes:
|
||||
# - mode: access -> untagged member of `pvid`; mode: trunk -> tagged member of
|
||||
# each id in `tagged_vlans`, with `pvid` as the native (untagged) VLAN.
|
||||
# - trunk pvid: 1 means untagged frames on the uplink land in VLAN 1 (unused in a
|
||||
# hardened design). Decide deliberately whether the uplink should carry any
|
||||
# untagged traffic; set pvid to an intended native VLAN or leave 1 as a dead end.
|
||||
# - the bridge (CPU) is tagged ONLY on switch_mgmt_vlan_id (see vlans.yml).
|
||||
# ----- VLANs + per-port map (all untagged access; no trunks) -----
|
||||
# DATA = flat 10.2.30.0/24 (uplink + device ports); MGMT = isolated admin VLAN.
|
||||
switch_vlans:
|
||||
- {id: 30, name: "data"}
|
||||
- {id: 99, name: "mgmt"}
|
||||
- {id: 10, name: "members"}
|
||||
switch_bridge_ports:
|
||||
- {interface: "ether1", pvid: 10, mode: access}
|
||||
- {interface: "ether2", pvid: 10, mode: access}
|
||||
- {interface: "sfp-sfpplus1", pvid: 1, mode: trunk, tagged_vlans: [99, 10]}
|
||||
- {interface: "ether1", pvid: 30, mode: access} # copper uplink
|
||||
- {interface: "ether2", pvid: 30, mode: access}
|
||||
- {interface: "ether3", pvid: 30, mode: access}
|
||||
- {interface: "ether4", pvid: 30, mode: access}
|
||||
- {interface: "ether5", pvid: 30, mode: access}
|
||||
- {interface: "ether6", pvid: 30, mode: access}
|
||||
- {interface: "ether7", pvid: 30, mode: access}
|
||||
- {interface: "sfp-sfpplus1", pvid: 30, mode: access}
|
||||
- {interface: "sfp-sfpplus2", pvid: 30, mode: access}
|
||||
- {interface: "ether8", pvid: 99, mode: access} # dedicated mgmt port
|
||||
|
||||
# Firmware: pinned at the version already installed (no upgrade planned now).
|
||||
switch_firmware_target: "7.19.6"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ switch_mgmt_vlan_id: 99
|
|||
switch_mgmt_address: "192.168.88.1/24" # PLACEHOLDER — override in host_vars
|
||||
switch_mgmt_gateway: "192.168.88.254" # PLACEHOLDER — override in host_vars
|
||||
switch_dns_servers: "192.168.88.254"
|
||||
switch_ntp_enabled: true # set false for an isolated mgmt plane
|
||||
switch_ntp_servers: "192.168.88.254"
|
||||
|
||||
# Services to disable for hardening (winbox kept on by default for recovery)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,18 @@
|
|||
- /ip/dns/set servers="{{ switch_dns_servers }}" allow-remote-requests=no
|
||||
changed_when: false
|
||||
|
||||
- name: Configure NTP client
|
||||
- name: Enable NTP client
|
||||
community.routeros.command:
|
||||
commands:
|
||||
- /system/ntp/client/set enabled=yes servers="{{ switch_ntp_servers }}"
|
||||
when: switch_ntp_enabled | bool
|
||||
changed_when: false
|
||||
|
||||
- name: Disable NTP client (isolated mgmt plane has no upstream time source)
|
||||
community.routeros.command:
|
||||
commands:
|
||||
- /system/ntp/client/set enabled=no
|
||||
when: not (switch_ntp_enabled | bool)
|
||||
changed_when: false
|
||||
|
||||
- name: Disable unused IP services (hardening; winbox kept for recovery)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,22 @@
|
|||
interface="{{ switch_bridge_name }}" vlan-id={{ switch_mgmt_vlan_id }} }
|
||||
changed_when: false
|
||||
|
||||
- name: Assign the management IP address
|
||||
# On a defconf switch the mgmt IP lives directly on the bare `bridge`; it must move to
|
||||
# vlan-mgmt (same address can't be on both). Removing it drops a session reaching the
|
||||
# switch THROUGH the bridge, so during the first cutover this is done out-of-band as one
|
||||
# detached flip (see the design doc's runbook), not by a straight play run. In steady
|
||||
# state both tasks below are no-ops.
|
||||
- name: Remove the legacy management IP from the bare bridge interface
|
||||
community.routeros.command:
|
||||
commands:
|
||||
- >-
|
||||
:if ([:len [/ip/address/find interface="{{ switch_bridge_name }}"
|
||||
address="{{ switch_mgmt_address }}"]] > 0)
|
||||
do={ /ip/address/remove [find interface="{{ switch_bridge_name }}"
|
||||
address="{{ switch_mgmt_address }}"] }
|
||||
changed_when: false
|
||||
|
||||
- name: Assign the management IP address to vlan-mgmt
|
||||
community.routeros.command:
|
||||
commands:
|
||||
- >-
|
||||
|
|
@ -92,6 +107,7 @@
|
|||
:if ([:len [/ip/route/find dst-address="0.0.0.0/0"]] = 0)
|
||||
do={ /ip/route/add dst-address=0.0.0.0/0
|
||||
gateway="{{ switch_mgmt_gateway }}" }
|
||||
when: switch_mgmt_gateway | length > 0
|
||||
changed_when: false
|
||||
|
||||
- name: Enable VLAN filtering (LAST — prove mgmt reachability first)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue