--- # ------------------------------------------------------------------------------ # FILE: roles/llm-inference-multimodel/tasks/firewall.yml # DESCRIPTION: Phase 3 — scope :8002 (production Qwen) exposure. # # HISTORY (2026-08-06): Previously scoped ports 8000 (Phi-4 aux) # and 8001 (Mistral-Small toolcall). Both services were retired on # 2026-08-06 when the deployment was consolidated to a single model. # See git log for the prior rule definitions. # # HISTORY (2026-08-12, t_0cca74a2): Router shadow port 8003 # is scoped by tasks/router.yml (its own router_firewall phase), # not by this file. This file only manages the production :8002 rule. # # Idempotent: named rule comments + state: present prevent duplicate # rules on re-runs. # ------------------------------------------------------------------------------ - name: Check whether ufw is installed/active ansible.builtin.command: cmd: ufw status register: llm_ufw_status changed_when: false failed_when: false become: true - name: WARNING — ufw not active, firewall scoping cannot be applied ansible.builtin.debug: msg: >- ufw does not appear to be active on this host (`ufw status` returned: {{ llm_ufw_status.stdout | default('n/a') }}). Firewall scoping for port {{ llm_qwen_port }} was skipped. Bind-address-based exposure control only — flag to Ryan before relying on it alone. when: "'Status: active' not in (llm_ufw_status.stdout | default(''))" - name: Allow Qwen production port ({{ llm_qwen_port }}) from the Hermes source subnet community.general.ufw: rule: allow port: "{{ llm_qwen_port | string }}" proto: tcp src: "{{ llm_allowed_source_cidr }}" comment: "llm-inference-multimodel: Qwen production (:{{ llm_qwen_port }}) — scoped to Hermes subnet" become: true when: "'Status: active' in (llm_ufw_status.stdout | default(''))" - name: Report firewall scoping applied ansible.builtin.debug: msg: >- Firewall scoping applied for port {{ llm_qwen_port }}, restricted to source {{ llm_allowed_source_cidr }}. Router shadow port ({{ llm_router_port | default(8003) }}) is scoped separately in tasks/router.yml (router_firewall phase).