From 265299166c78741cac62d2dbfb6815bdf3ab4a01 Mon Sep 17 00:00:00 2001 From: "l.covela" Date: Mon, 19 Jan 2026 15:56:44 +0100 Subject: [PATCH] Ajouter create-test-stack.yml --- create-test-stack.yml | 128 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 create-test-stack.yml diff --git a/create-test-stack.yml b/create-test-stack.yml new file mode 100644 index 0000000..3151418 --- /dev/null +++ b/create-test-stack.yml @@ -0,0 +1,128 @@ +--- +- name: Create a test Portainer stack via SSH tunnel + hosts: localhost + connection: local + gather_facts: false + + vars: + # Bastion SSH + bastion_host: bdc.cci17.fr + bastion_port: 17100 + bastion_user: ansible + + # Portainer via tunnel (local fixe) + local_portainer_url: "https://127.0.0.1:9443" + + # Stack test + stack_name: "test-stack-semaphore" + # type=2 => Docker standalone (Compose) ; type=1 => Swarm + stack_type: 2 + + # Endpoint: si tu connais l'ID, mets-le ici (sinon on prend le 1er endpoint) + endpoint_id: "" + + # Tunnel + ssh_control_socket: "/tmp/ssh-tunnel-portainer-9443.sock" + ssh_log: "/tmp/ssh-tunnel-portainer-9443.log" + + # Compose minimal pour test + stack_compose: | + services: + web: + image: nginx:alpine + restart: unless-stopped + # Pas d'exposition de port : on teste juste que la stack se crée et démarre + # Si tu veux la voir, on pourra ajouter Traefik plus tard. + + tasks: + - block: + - name: Check local port 9443 is not already in use + shell: "ss -lnt | grep -q ':9443 '" + register: port_in_use + changed_when: false + failed_when: port_in_use.rc == 0 + + - name: Open SSH tunnel to Portainer (fixed local port 9443) + shell: | + rm -f "{{ ssh_log }}" + 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:9443:10.30.0.151:9443 \ + {{ bastion_user }}@{{ bastion_host }} \ + > "{{ ssh_log }}" 2>&1 + changed_when: true + + - name: Wait for local tunnel port 9443 + wait_for: + host: 127.0.0.1 + port: 9443 + delay: 1 + timeout: 20 + + - name: Check Portainer is reachable + uri: + url: "{{ local_portainer_url }}/api/status" + method: GET + validate_certs: false + headers: + X-API-Key: "{{ lookup('env','PORTAINER_API_KEY') }}" + status_code: [200] + register: status_check + + - name: Get endpoints list + uri: + url: "{{ local_portainer_url }}/api/endpoints" + method: GET + validate_certs: false + headers: + X-API-Key: "{{ lookup('env','PORTAINER_API_KEY') }}" + status_code: [200] + register: endpoints_resp + + - name: Pick endpoint_id (use provided or first) + set_fact: + endpoint_id_effective: >- + {{ + (endpoint_id | string | length > 0) + | ternary(endpoint_id | int, (endpoints_resp.json[0].Id | int)) + }} + + - name: Create test stack (Compose, method=string) + uri: + url: "{{ local_portainer_url }}/api/stacks?type={{ stack_type }}&method=string&endpointId={{ endpoint_id_effective }}" + method: POST + validate_certs: false + headers: + X-API-Key: "{{ lookup('env','PORTAINER_API_KEY') }}" + Content-Type: "application/json" + body_format: json + body: + Name: "{{ stack_name }}" + StackFileContent: "{{ stack_compose }}" + Env: [] + # Si la stack existe déjà, Portainer peut renvoyer une erreur 409 + status_code: [200, 201, 409] + register: create_stack_resp + + - name: Result + debug: + msg: + - "✅ API status: {{ status_check.status }}" + - "✅ endpointId utilisé: {{ endpoint_id_effective }}" + - "✅ Create stack HTTP status: {{ create_stack_resp.status }}" + - "ℹ️ Si status=409: la stack '{{ stack_name }}' existe déjà." + + always: + - name: Close SSH tunnel + shell: > + test -S {{ ssh_control_socket }} && + ssh -p {{ bastion_port }} -S {{ ssh_control_socket }} -O exit + {{ bastion_user }}@{{ bastion_host }} || true + ignore_errors: true