--- # Validate edge ingress readiness for an externally-routed Swarm service. # Usage: # ansible-playbook -i inventory/hosts.ini playbooks/preflight/validate_edge_ingress.yml \ # -e "service_fqdn=git.castaldifamily.com" \ # -e "backend_port=8251" - name: Validate external Traefik ingress path hosts: localhost connection: local gather_facts: false vars_files: - ../../group_vars/all.yml vars: service_fqdn: "git.castaldifamily.com" backend_port: 8251 # backend_host controls which IP Heimdall probes for the backend. # Default: swarm.bind_ip — correct for Swarm services (routing mesh exposes published # ports on all nodes). Override with edge_routing.integration.bind_ip for services # running on Watchtower (Grafana, Dozzle, Uptime Kuma, etc.). backend_host: "{{ edge_routing.swarm.bind_ip }}" allowed_external_http_codes: - "200" - "301" - "302" - "401" - "403" tasks: - name: Build derived probe URLs ansible.builtin.set_fact: backend_url: "http://{{ backend_host }}:{{ backend_port }}" external_url: "https://{{ service_fqdn }}" primary_swarm_manager: "{{ groups['swarm_managers'][0] }}" - name: Validate required variables ansible.builtin.assert: that: - edge_routing.edge_host.name | length > 0 - edge_routing.integration.bind_ip | length > 0 - edge_routing.integration.redis_addr | length > 0 - service_fqdn | length > 0 fail_msg: "Missing required edge routing or service probe inputs." - name: Probe service backend from edge host ansible.builtin.command: >- curl -sS -o /dev/null -w %{http_code} --max-time 6 {{ backend_url }} delegate_to: "{{ edge_routing.edge_host.name }}" register: edge_backend_probe changed_when: false failed_when: edge_backend_probe.stdout == "000" - name: Probe public service endpoint from controller ansible.builtin.command: >- curl -sS -k -o /dev/null -w %{http_code} --max-time 10 {{ external_url }} register: external_probe changed_when: false - name: Check external endpoint health code ansible.builtin.assert: that: - external_probe.stdout in allowed_external_http_codes fail_msg: >- External endpoint {{ external_url }} returned HTTP {{ external_probe.stdout }}. Expected one of {{ allowed_external_http_codes | join(', ') }}. - name: Capture traefik-kop logs for publication hints ansible.builtin.command: docker service logs traefik-kop_traefik-kop --tail 120 delegate_to: "{{ primary_swarm_manager }}" register: traefik_kop_logs changed_when: false failed_when: false - name: Report ingress validation summary ansible.builtin.debug: msg: - "Edge backend probe (from {{ edge_routing.edge_host.name }}): {{ backend_url }} -> HTTP {{ edge_backend_probe.stdout }}" - "External probe (from controller): {{ external_url }} -> HTTP {{ external_probe.stdout }}" - "Traefik-kop log sample lines: {{ (traefik_kop_logs.stdout_lines | default([]))[:8] }}"