diff --git a/ping-portainer.yml b/ping-portainer.yml index 190a0c2..aed60f4 100644 --- a/ping-portainer.yml +++ b/ping-portainer.yml @@ -5,55 +5,88 @@ gather_facts: false vars: + # Bastion SSH bastion_host: bdc.cci17.fr bastion_port: 17100 bastion_user: ansible + # Portainer interne portainer_ip: 10.30.0.151 portainer_port: 9443 + # Port local aléatoire pour éviter les collisions entre jobs local_port: "{{ 20000 + (9999 | random) }}" + + # Socket ControlMaster pour fermer proprement le tunnel ssh_control_socket: "/tmp/ssh-tunnel-{{ local_port }}.sock" tasks: - block: - - name: Open SSH tunnel (local -> portainer via bastion) - shell: > - ssh - -p {{ bastion_port }} - -o ExitOnForwardFailure=yes - -o StrictHostKeyChecking=no - -o UserKnownHostsFile=/dev/null - -o ServerAliveInterval=10 - -o ServerAliveCountMax=3 - -M -S {{ ssh_control_socket }} - -f -N - -L 127.0.0.1:{{ local_port }}:{{ portainer_ip }}:{{ portainer_port }} - {{ bastion_user }}@{{ bastion_host }} - changed_when: true - - name: Wait for local tunnel port + - name: Open SSH tunnel (local -> portainer via bastion) + shell: | + ssh -p {{ bastion_port }} \ + -o ExitOnForwardFailure=yes \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o ServerAliveInterval=10 \ + -o ServerAliveCountMax=3 \ + -o ConnectTimeout=10 \ + -M -S {{ ssh_control_socket }} \ + -f -N \ + -L 127.0.0.1:{{ local_port }}:{{ portainer_ip }}:{{ portainer_port }} \ + {{ bastion_user }}@{{ bastion_host }} + register: tunnel_open + changed_when: true + failed_when: tunnel_open.rc != 0 + + # Diagnostic utile : montre si SSH a renvoyé quelque chose + - name: Debug tunnel open result (rc/stdout/stderr) + debug: + msg: + - "ssh rc={{ tunnel_open.rc }}" + - "stdout={{ tunnel_open.stdout | default('') }}" + - "stderr={{ tunnel_open.stderr | default('') }}" + + - name: Wait for local tunnel port to be listening wait_for: host: 127.0.0.1 port: "{{ local_port }}" - timeout: 20 + delay: 1 + timeout: 30 + + - name: Verify local port is listening (extra check) + shell: "ss -lnt | grep -q ':{{ local_port }} '" + changed_when: false - name: HTTPS check Portainer through tunnel uri: url: "https://127.0.0.1:{{ local_port }}/" method: GET validate_certs: false - status_code: [200, 301, 302, 403] + return_content: false + status_code: [200, 301, 302, 401, 403] register: portainer_check - name: OK debug: msg: "✅ Portainer joignable via tunnel (status {{ portainer_check.status }})" + rescue: + - name: Explain common causes when tunnel fails + debug: + msg: + - "❌ Le tunnel n'a pas pu être validé." + - "Causes fréquentes :" + - "1) Sur OPNsense/bastion, 'Allow SSH port forwarding / TCP forwarding' n'est pas activé." + - "2) Le bastion ne peut pas joindre {{ portainer_ip }}:{{ portainer_port }} (routage / firewall)." + - "3) La clé SSH/credential utilisée par Semaphore n'est pas celle attendue (auth SSH)." + - "Regarde le 'stderr' affiché juste avant pour l'erreur exacte." + always: - - name: Close tunnel if opened + - name: Close tunnel if opened (ControlMaster) shell: > test -S {{ ssh_control_socket }} && ssh -p {{ bastion_port }} -S {{ ssh_control_socket }} -O exit {{ bastion_user }}@{{ bastion_host }} || true - ignore_errors: true \ No newline at end of file + ignore_errors: true