--- # --------------------------------------------------------------------------- # 1. System prerequisites (run as root via become) # --------------------------------------------------------------------------- - name: Install system packages required by Hermes installer ansible.builtin.apt: name: - git - curl - ffmpeg - ripgrep state: present update_cache: true become: true - name: Install Node.js 22 (required for browser automation and WhatsApp bridge) block: - name: Download NodeSource setup script ansible.builtin.get_url: url: https://deb.nodesource.com/setup_22.x dest: /tmp/nodesource_setup.sh mode: "0755" - name: Run NodeSource setup script ansible.builtin.command: bash /tmp/nodesource_setup.sh args: creates: /etc/apt/sources.list.d/nodesource.list - name: Install nodejs ansible.builtin.apt: name: nodejs state: present update_cache: true become: true # --------------------------------------------------------------------------- # 2. Install Playwright system deps for Chromium (root-only step) # Per docs: this is the one thing that genuinely needs root. # Skipped entirely if hermes_skip_browser is true. # --------------------------------------------------------------------------- - name: Install Playwright Chromium system dependencies ansible.builtin.command: npx --yes playwright install-deps chromium become: true when: not hermes_skip_browser changed_when: true environment: DEBIAN_FRONTEND: noninteractive # --------------------------------------------------------------------------- # 3. Create dedicated hermes service user # --------------------------------------------------------------------------- - name: Create hermes group ansible.builtin.group: name: "{{ hermes_group }}" state: present system: true become: true - name: Create hermes user ansible.builtin.user: name: "{{ hermes_user }}" group: "{{ hermes_group }}" home: "{{ hermes_home }}" shell: /bin/bash system: true create_home: true comment: "Hermes Agent service account" become: true - name: Grant hermes user passwordless sudo ansible.builtin.copy: content: "hermes ALL=(ALL) NOPASSWD:ALL\n" dest: /etc/sudoers.d/hermes owner: root group: root mode: "0440" validate: /usr/sbin/visudo -cf %s become: true - name: Ensure hermes home directory has correct permissions ansible.builtin.file: path: "{{ hermes_home }}" owner: "{{ hermes_user }}" group: "{{ hermes_group }}" mode: "0750" state: directory become: true # --------------------------------------------------------------------------- # 4. Run the Hermes installer as the hermes user # --------------------------------------------------------------------------- - name: Check if hermes is already installed ansible.builtin.stat: path: "{{ hermes_home }}/.hermes/hermes-agent/venv/bin/hermes" register: hermes_binary - name: Run Hermes installer as hermes user ansible.builtin.shell: | curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh \ | bash -s -- --skip-setup{% if hermes_skip_browser %} --skip-browser{% endif %} args: executable: /bin/bash become: true become_user: "{{ hermes_user }}" environment: HOME: "{{ hermes_home }}" PATH: "{{ hermes_home }}/.local/bin:/usr/local/bin:/usr/bin:/bin" when: not hermes_binary.stat.exists changed_when: true # --------------------------------------------------------------------------- # 5. Symlink hermes binary into system PATH # Per docs: service accounts often lack ~/.local/bin in PATH; symlink # into /usr/local/bin so hermes is always accessible. # --------------------------------------------------------------------------- - name: Symlink hermes binary to system PATH ansible.builtin.file: src: "{{ hermes_home }}/.hermes/hermes-agent/venv/bin/hermes" dest: "{{ hermes_bin_symlink }}" state: link force: true become: true # --------------------------------------------------------------------------- # 6. Install systemd service unit # NOTE: The service starts in 'gateway' mode for persistent operation. # You must run 'sudo -u hermes hermes setup' interactively on first boot # to configure your LLM provider and any messaging gateways before # enabling the service. # --------------------------------------------------------------------------- - name: Deploy hermes systemd service unit ansible.builtin.template: src: hermes.service.j2 dest: /etc/systemd/system/{{ hermes_service_name }}.service owner: root group: root mode: "0644" become: true notify: - reload systemd - name: Flush handlers to reload systemd now ansible.builtin.meta: flush_handlers - name: Enable hermes service (but do not start — config required first) ansible.builtin.systemd: name: "{{ hermes_service_name }}" enabled: true state: stopped become: true