# --- Firewall in der VM: SSH aus dem LAN, Sprachdienste nur von appsrv08, sonst nichts --- # Reihenfolge wichtig: SSH-Regel vor dem Einschalten, sonst sperrt sich Ansible aus. - name: ufw installieren ansible.builtin.apt: name: ufw state: present - name: ufw – SSH aus dem LAN erlauben community.general.ufw: rule: allow from_ip: "{{ nex_speech_ssh_from }}" port: "22" proto: tcp comment: ssh-lan - name: ufw – Sprachdienste nur von appsrv08 community.general.ufw: rule: allow from_ip: "{{ nex_speech_allow_from }}" port: "{{ item.port | string }}" proto: tcp comment: "{{ item.name }}" loop: - {name: nex-stt, port: "{{ nex_speech_stt_port }}"} - {name: nex-tts, port: "{{ nex_speech_tts_port }}"} - name: ufw – eingehend sonst ablehnen, ausgehend erlauben community.general.ufw: direction: "{{ item.direction }}" default: "{{ item.policy }}" loop: - {direction: incoming, policy: deny} - {direction: outgoing, policy: allow} - name: ufw einschalten community.general.ufw: state: enabled # Compose baut nur mit buildx (BuildKit); der Altbau-Builder ist in Docker 29 veraltet - name: docker-buildx installieren ansible.builtin.apt: name: docker-buildx state: present # --- Modelle --- - name: Modellverzeichnisse ansible.builtin.file: path: "{{ nex_speech_models_dir }}/{{ item }}" state: directory mode: "0755" loop: [whisper, piper] - name: Modelle laden (Prüfsumme gegen Hugging Face) ansible.builtin.get_url: url: "{{ item.url }}" dest: "{{ nex_speech_models_dir }}/{{ item.dest }}" checksum: "{{ item.checksum }}" mode: "0644" timeout: 120 loop: "{{ nex_speech_models }}" loop_control: label: "{{ item.dest }}" # --- Compose-Projekt --- - name: Compose-Dateien kopieren ansible.builtin.copy: src: "{{ playbook_dir }}/../../../../deploy/compose/nex-speech/" dest: "{{ nex_speech_dir }}/" mode: u=rwX,g=rX,o=rX # Clone auf ops ist 0600; der Piper-Container läuft als nobody directory_mode: "0755" register: nex_speech_files - name: .env schreiben (keine Geheimnisse) ansible.builtin.copy: dest: "{{ nex_speech_dir }}/.env" mode: "0644" content: | # Verwaltet von Ansible (Rolle nex-speech) {% for k, v in nex_speech_env.items() %} {{ k }}={{ v }} {% endfor %} register: nex_speech_envfile # Bauen dauert beim ersten Mal lange (whisper.cpp mit CUDA auf 4 Kernen, ca. 20–40 min) - name: Images bauen und Dienste starten community.docker.docker_compose_v2: project_src: "{{ nex_speech_dir }}" build: "{{ 'always' if (nex_speech_files.changed or nex_speech_envfile.changed) else 'policy' }}" state: present wait: false async: 3600 poll: 30 - name: Warten, bis beide Dienste gesund sind ansible.builtin.uri: url: "http://127.0.0.1:{{ item }}/health" status_code: 200 register: nex_speech_health until: nex_speech_health.status == 200 retries: 60 delay: 10 loop: ["{{ nex_speech_stt_port }}", "{{ nex_speech_tts_port }}"]