--- # LiteLLM — OpenAI-compatible proxy that fronts Meridian's Anthropic # /v1/messages endpoint. Lets Anthropic-unfriendly clients (Pulse's # OpenAI provider, paperless-ai, etc.) talk to the Max sub via Meridian. - name: Ensure python3-venv is installed (LiteLLM runs in a venv) apt: name: - python3-venv - python3-pip state: present - name: Ensure litellm system user user: name: "{{ litellm_user }}" system: true home: "{{ litellm_home }}" shell: /usr/sbin/nologin create_home: true state: present - name: Ensure litellm home perms file: path: "{{ litellm_home }}" state: directory owner: "{{ litellm_user }}" group: "{{ litellm_user }}" mode: '0755' # Pip install runs as root (LXC filesystem doesn't support the ACL flip # Ansible uses for become_user). Venv contents end up root-owned, which is # fine — systemd runs the proxy as the litellm user and only needs read+exec. - name: Create litellm venv command: python3 -m venv {{ litellm_venv }} args: creates: "{{ litellm_venv }}/bin/python" - name: Upgrade pip + wheel + setuptools in venv pip: name: - pip - wheel - setuptools state: latest virtualenv: "{{ litellm_venv }}" virtualenv_command: python3 -m venv - name: Install LiteLLM into venv pip: name: "{{ litellm_package_spec }}" virtualenv: "{{ litellm_venv }}" virtualenv_command: python3 -m venv notify: restart litellm - name: Resolve litellm binary stat: path: "{{ litellm_venv }}/bin/litellm" register: litellm_bin - name: Fail if litellm binary missing fail: msg: "litellm not installed at {{ litellm_venv }}/bin/litellm" when: not litellm_bin.stat.exists - name: Drop LiteLLM config template: src: litellm-config.yaml.j2 dest: "{{ litellm_home }}/config.yaml" owner: "{{ litellm_user }}" group: "{{ litellm_user }}" mode: '0640' notify: restart litellm - name: Drop systemd environment file (master key) template: src: litellm.env.j2 dest: "{{ litellm_home }}/litellm.env" owner: "{{ litellm_user }}" group: "{{ litellm_user }}" mode: '0600' notify: restart litellm no_log: true - name: Deploy litellm systemd unit template: src: litellm.service.j2 dest: /etc/systemd/system/litellm.service owner: root group: root mode: '0644' notify: - reload systemd - restart litellm - name: Flush handlers (reload systemd before enable) meta: flush_handlers - name: Enable + start litellm systemd: name: litellm enabled: true state: started daemon_reload: true - name: Wait for LiteLLM /health uri: url: "http://127.0.0.1:{{ litellm_port }}/health/liveliness" status_code: 200 register: litellm_health until: litellm_health.status is defined and litellm_health.status == 200 retries: 20 delay: 3 failed_when: false