From fd58ee2c16d9471a6415ec3af7dca16f9292467b Mon Sep 17 00:00:00 2001 From: Ruakij Date: Sat, 24 Oct 2026 15:55:22 +0000 Subject: [PATCH] journal_upload: ship the journal to VictoriaLogs with systemd-journal-upload over NetBird --- journal_upload/defaults/main.yml | 12 +++++++ journal_upload/handlers/main.yml | 6 ++++ journal_upload/tasks/main.yml | 56 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 journal_upload/defaults/main.yml create mode 100644 journal_upload/handlers/main.yml create mode 100644 journal_upload/tasks/main.yml diff --git a/journal_upload/defaults/main.yml b/journal_upload/defaults/main.yml new file mode 100644 index 0000000..55d6df1 --- /dev/null +++ b/journal_upload/defaults/main.yml @@ -0,0 +1,12 @@ +--- +journal_upload: + # Ingest route of VictoriaLogs (insert path only, NetBird sources, basic auth per host). + # The public DNS answers with the cluster's public address, where the route rejects + # every source outside NetBird; /etc/hosts pins the name to the NetBird addresses below. + host: "" + path: /insert/journald + # NetBird addresses of the Traefik nodes. The client tries them in this order when one is down. + addresses: [] + # Basic auth credential; the user is the host's entry in the Secret vl-ingest-users. + user: "{{ inventory_hostname }}" + password: "" diff --git a/journal_upload/handlers/main.yml b/journal_upload/handlers/main.yml new file mode 100644 index 0000000..bd06f75 --- /dev/null +++ b/journal_upload/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Restart systemd-journal-upload + ansible.builtin.systemd: + name: systemd-journal-upload + state: restarted + ignore_errors: "{{ ansible_check_mode }}" diff --git a/journal_upload/tasks/main.yml b/journal_upload/tasks/main.yml new file mode 100644 index 0000000..54fceff --- /dev/null +++ b/journal_upload/tasks/main.yml @@ -0,0 +1,56 @@ +--- +# Ships the whole journal to VictoriaLogs. The uploader keeps the cursor of the last uploaded +# entry in its state directory, so a restart resumes where it stopped. +- name: Require the endpoint and the credential + ansible.builtin.assert: + that: + - journal_upload.host | length > 0 + - journal_upload.addresses | length > 0 + - journal_upload.user | length > 0 + - journal_upload.password | length > 0 + fail_msg: journal_upload.host, addresses, user and password must be set + +- name: Install the journal uploader + ansible.builtin.apt: + name: systemd-journal-remote + install_recommends: false + state: present + +- name: Pin the ingest name to the NetBird addresses + ansible.builtin.blockinfile: + path: /etc/hosts + marker: "# {mark} journal_upload" + block: | + {% for address in journal_upload.addresses %} + {{ address }} {{ journal_upload.host }} + {% endfor %} + notify: Restart systemd-journal-upload + +- name: Create the uploader config directory + ansible.builtin.file: + path: /etc/systemd/journal-upload.conf.d + state: directory + mode: "0755" + +# The service runs as a dynamic user, which reads the file after the manager dropped privileges. +- name: Configure the upload URL + ansible.builtin.copy: + dest: /etc/systemd/journal-upload.conf.d/10-victorialogs.conf + mode: "0644" + content: | + [Upload] + URL=https://{{ journal_upload.user }}:{{ journal_upload.password }}@{{ journal_upload.host }}{{ journal_upload.path }} + # No client certificate; the server certificate is checked against the system CAs. + ServerKeyFile=- + ServerCertificateFile=- + TrustedCertificateFile=/etc/ssl/certs/ca-certificates.crt + notify: Restart systemd-journal-upload + no_log: true + +- name: Enable the journal uploader + ansible.builtin.systemd: + name: systemd-journal-upload + enabled: true + state: started + # Check mode does not install the package. + ignore_errors: "{{ ansible_check_mode }}"