diff --git a/ansible/playbooks/saas/roles/litellm/README.md b/ansible/playbooks/saas/roles/litellm/README.md new file mode 100644 index 0000000..dcb700f --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/README.md @@ -0,0 +1 @@ +# Role: `litellm` diff --git a/ansible/playbooks/saas/roles/litellm/defaults/main.yml b/ansible/playbooks/saas/roles/litellm/defaults/main.yml new file mode 100644 index 0000000..fd899ea --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/defaults/main.yml @@ -0,0 +1,23 @@ +--- +# Environments variables +litellm_env: + - key: LITELLM_MASTER_KEY + value: sk-1234 + - key: LITELLM_SALT_KEY + value: sk-1234 + - key: DATABASE_URL + value: postgresql://llmproxy:dbpassword9090@db:5432/litellm + - key: STORE_MODEL_IN_DB + value: true + - key: OVHCLOUD_API_KEY + value: changeme + +# Default configuration +litellm_config: + model_list: + - model_name: ovhcloud/gpt-oss-120b + litellm_params: + model: ovhcloud/gpt-oss-120b + api_key: os.environ/OVHCLOUD_API_KEY + +litellm_dbhost: localhost diff --git a/ansible/playbooks/saas/roles/litellm/tasks/backup.yml b/ansible/playbooks/saas/roles/litellm/tasks/backup.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/tasks/backup.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/playbooks/saas/roles/litellm/tasks/build.yml b/ansible/playbooks/saas/roles/litellm/tasks/build.yml new file mode 100644 index 0000000..6840669 --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/tasks/build.yml @@ -0,0 +1,14 @@ +--- +- name: Include upstream variables + ansible.builtin.include_vars: upstream.yml + +- name: Set custom variables + ansible.builtin.set_fact: + image_version: "{{ latest_version }}" + image_name: "{{ image.name }}" + image_labels: "{{ image.labels }}" + image_build: "{{ image.build }}" + +- name: End playbook if no new version + ansible.builtin.meta: end_host + when: softwares[image.name] is defined and softwares[image.name].version == image_version diff --git a/ansible/playbooks/saas/roles/litellm/tasks/destroy.yml b/ansible/playbooks/saas/roles/litellm/tasks/destroy.yml new file mode 100644 index 0000000..e00b7de --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/tasks/destroy.yml @@ -0,0 +1,11 @@ +--- +- name: Stop nomad job + ansible.builtin.include_role: + name: nomad + tasks_from: job_stop.yml + +- name: Remove software directory + ansible.builtin.file: + path: "{{ software_path }}" + state: absent + delegate_to: "{{ software.instance }}" \ No newline at end of file diff --git a/ansible/playbooks/saas/roles/litellm/tasks/main.yml b/ansible/playbooks/saas/roles/litellm/tasks/main.yml new file mode 100644 index 0000000..6bda2d6 --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/tasks/main.yml @@ -0,0 +1,50 @@ +--- +- name: Install mandatories packages + ansible.builtin.apt: + pkg: + - python3-psycopg2 + +- name: Create postgresql database + community.postgresql.postgresql_db: + login_password: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='passwd', missing='error') }}" + login_host: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='service_name', missing='error') }}" + login_user: postgres + name: "{{ service_name }}" + encoding: UTF8 + state: present + +- name: Create postgresql user + community.postgresql.postgresql_user: + login_password: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='passwd', missing='error') }}" + login_host: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='service_name', missing='error') }}" + login_user: postgres + login_db: "{{ service_name }}" + name: "{{ service_name }}" + password: "{{ lookup('simple-stack-ui', type='secret', key=domain, subkey='litellm_dbpasswd', missing='create', length=12) }}" + state: present + +- name: Create postgresql privileges + community.postgresql.postgresql_privs: + login_password: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='passwd', missing='error') }}" + login_host: "{{ lookup('simple-stack-ui', type='secret', key=software.litellm_dbhost, subkey='service_name', missing='error') }}" + login_user: postgres + db: "{{ service_name }}" + roles: "{{ service_name }}" + type: schema + objs: public + privs: CREATE + state: present + +- name: Copy nomad job + ansible.builtin.template: + src: nomad.hcl + dest: "/var/tmp/{{ domain }}.nomad" + owner: root + group: root + mode: '0600' + become: true + +- name: Run nomad job + ansible.builtin.include_role: + name: nomad + tasks_from: job_run.yml diff --git a/ansible/playbooks/saas/roles/litellm/tasks/restore.yml b/ansible/playbooks/saas/roles/litellm/tasks/restore.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/tasks/restore.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/playbooks/saas/roles/litellm/templates/nomad.hcl b/ansible/playbooks/saas/roles/litellm/templates/nomad.hcl new file mode 100644 index 0000000..4e80549 --- /dev/null +++ b/ansible/playbooks/saas/roles/litellm/templates/nomad.hcl @@ -0,0 +1,78 @@ +job "{{ domain }}" { + region = "{{ fact_instance.region }}" + datacenters = ["{{ fact_instance.datacenter }}"] + type = "service" + +{% if software.constraints is defined and software.constraints.location is defined %} + constraint { + attribute = "${meta.location}" + set_contains = "{{ software.constraints.location }}" + } +{% endif %} + + constraint { + attribute = "${meta.instance}" + set_contains = "{{ software.instance }}" + } + + group "{{ domain }}" { + count = 1 + + network { + port "litellm" { + to = 4000 +{% if software.static_port is defined %} + static = {{ software.static_port }} +{% endif %} + } + } + + service { + name = "{{ service_name }}" + port = "litellm" + provider = "nomad" + tags = [ + {{ lookup('template', '../../traefik/templates/traefik_tag.j2') | indent(8) }} + ] + check { + type = "http" + path = "/health/liveliness" + interval = "30s" + timeout = "10s" + } + } + + task "{{ domain }}-milvus" { + driver = "docker" + + template { + change_mode = "restart" + destination = "local/config.yaml" + perms = "644" + data = <