diff --git a/roles/loki/.ansible-lint b/roles/loki/.ansible-lint new file mode 100644 index 0000000..f865478 --- /dev/null +++ b/roles/loki/.ansible-lint @@ -0,0 +1,16 @@ +--- +profile: production +strict: true + +# Enable checking of loop variable prefixes in roles +loop_var_prefix: "^(__|{role}_)" + +skip_list: + - var-naming[no-role-prefix] + +warn_list: + - role-name[path] + - var-naming[no-role-prefix] + +exclude_paths: + - .github/ diff --git a/roles/loki/.gitignore b/roles/loki/.gitignore new file mode 100644 index 0000000..8cd0df3 --- /dev/null +++ b/roles/loki/.gitignore @@ -0,0 +1,2 @@ +.vscode +.idea \ No newline at end of file diff --git a/roles/loki/.yamllint b/roles/loki/.yamllint new file mode 100644 index 0000000..611db54 --- /dev/null +++ b/roles/loki/.yamllint @@ -0,0 +1,8 @@ +--- +rules: + brackets: + forbid: false + min-spaces-inside: 0 + max-spaces-inside: 2 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: 2 diff --git a/roles/loki/README.md b/roles/loki/README.md new file mode 100644 index 0000000..8a05ac1 --- /dev/null +++ b/roles/loki/README.md @@ -0,0 +1,43 @@ +loki +========= + +Installs Loki as a `systemd` service. + +Requirements +------------ + +Role Variables +-------------- + +```yaml +loki_version: Loki version to be deployed +loki_storage_path: where to put Loki's files, including log data and positions (default: /data/loki) +loki_port: Loki will listen on this port (default: 3000) +``` + +Dependencies +------------ + +No + +Example Playbook +---------------- + +```yaml +roles: + - role: loki + loki_version: 2.7.3 +``` + + +License +------- + +MIT + +Author Information +------------------ + +Alexander Gorelyshev (corvus-migratorius@proton.me) and Danila Danilkin + +Genlab LLC diff --git a/roles/loki/defaults/main.yml b/roles/loki/defaults/main.yml new file mode 100644 index 0000000..08a7293 --- /dev/null +++ b/roles/loki/defaults/main.yml @@ -0,0 +1,4 @@ +--- +loki_version: 3.4.2 +loki_storage_path: /data/loki +loki_port: 3100 diff --git a/roles/loki/environment.ci.yml b/roles/loki/environment.ci.yml new file mode 100644 index 0000000..d96d2e1 --- /dev/null +++ b/roles/loki/environment.ci.yml @@ -0,0 +1,10 @@ +--- +name: ansible-loki +channels: + - conda-forge +dependencies: + - python~=3.12 + - pip>=22.2 + - pip: + - -r requirements.txt + - -r requirements.ci.txt diff --git a/roles/loki/environment.yml b/roles/loki/environment.yml new file mode 100644 index 0000000..bdd0220 --- /dev/null +++ b/roles/loki/environment.yml @@ -0,0 +1,9 @@ +--- +name: ansible-loki +channels: + - conda-forge +dependencies: + - python~=3.12 + - pip>=22.2 + - pip: + - -r requirements.txt diff --git a/roles/loki/handlers/main.yml b/roles/loki/handlers/main.yml new file mode 100644 index 0000000..e6d7f41 --- /dev/null +++ b/roles/loki/handlers/main.yml @@ -0,0 +1,10 @@ +--- +- name: "Restart the Loki daemon" + ansible.builtin.systemd: + name: loki + state: restarted + + +- name: "Reload the Loki daemon configuration" + ansible.builtin.systemd: + daemon_reload: true diff --git a/roles/loki/meta/main.yml b/roles/loki/meta/main.yml new file mode 100644 index 0000000..2ca0728 --- /dev/null +++ b/roles/loki/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + role_name: loki + namespace: genlab + author: "Danila Danilkin" + company: "Genlab, LLC" + description: "Deploy Loki as a systemd service" + license: "MIT" + min_ansible_version: "2.1" + + platforms: + - name: "Ubuntu" + versions: ["focal", "jammy"] + + galaxy_tags: [] + +dependencies: [] diff --git a/roles/loki/molecule/default/converge.yml b/roles/loki/molecule/default/converge.yml new file mode 100644 index 0000000..b95fe26 --- /dev/null +++ b/roles/loki/molecule/default/converge.yml @@ -0,0 +1,5 @@ +--- +- name: Converge + hosts: all + roles: + - role: genlab.common.loki diff --git a/roles/loki/molecule/default/molecule.yml b/roles/loki/molecule/default/molecule.yml new file mode 100644 index 0000000..de54042 --- /dev/null +++ b/roles/loki/molecule/default/molecule.yml @@ -0,0 +1,22 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: ubuntu + image: geerlingguy/docker-ubuntu2204-ansible:latest + pre_build_image: true + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true +provisioner: + name: ansible +verifier: + name: ansible +lint: | + set -e + yamllint . + ansible-lint . diff --git a/roles/loki/molecule/default/verify.yml b/roles/loki/molecule/default/verify.yml new file mode 100644 index 0000000..62dd143 --- /dev/null +++ b/roles/loki/molecule/default/verify.yml @@ -0,0 +1,33 @@ +--- +- name: Verify + hosts: all + gather_facts: false + any_errors_fatal: true + tasks: + # https://github.com/ansible/molecule/issues/3587#issuecomment-1158650179 + - name: "Include default vars" + ansible.builtin.include_vars: + dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/" + extensions: ['yml'] + + - name: "Sanity check the Loki daemon" + retries: 5 + delay: 1 + register: loki_this + failed_when: "loki_version not in loki_this.content" + ansible.builtin.uri: + url: "http://localhost:{{ loki_port }}/metrics" + return_content: true + + - name: "Ensure that locgli is installed and able to run" + register: loki_logcli + failed_when: loki_logcli.rc != 0 + changed_when: false + ansible.builtin.command: + cmd: logcli --version + + - name: "Check logcli version" + ansible.builtin.assert: + that: "'version {{ loki_version }}' in loki_logcli.stderr" + success_msg: "logcli version {{ loki_version }} is installed and working" + fail_msg: "logcli version {{ loki_version }} is not installed or not working correctly" diff --git a/roles/loki/renovate.json b/roles/loki/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/roles/loki/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/roles/loki/requirements.ci.txt b/roles/loki/requirements.ci.txt new file mode 100644 index 0000000..f99c76a --- /dev/null +++ b/roles/loki/requirements.ci.txt @@ -0,0 +1,6 @@ +ansible-lint +molecule==24.12.0 +molecule-plugins[docker] +docker~=7.1.0 +requests==2.31.0 # pinned to the latest version not breaking Docker SDK +yamllint diff --git a/roles/loki/requirements.txt b/roles/loki/requirements.txt new file mode 100644 index 0000000..92f8677 --- /dev/null +++ b/roles/loki/requirements.txt @@ -0,0 +1 @@ +ansible~=11.3.0 diff --git a/roles/loki/tasks/main.yml b/roles/loki/tasks/main.yml new file mode 100644 index 0000000..266744e --- /dev/null +++ b/roles/loki/tasks/main.yml @@ -0,0 +1,101 @@ +--- +- name: "Install unzip package" + ansible.builtin.apt: + name: unzip + state: present + cache_valid_time: 3600 + + +- name: "Create Loki directories" + with_items: + - {path: '/opt/loki', mode: '0755'} + - {path: '/etc/loki', mode: '0644'} + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: root + group: root + mode: "{{ item.mode }}" + + +- name: "Template Loki config file" + notify: "Restart the Loki daemon" + ansible.builtin.template: + src: "loki.yml.j2" + dest: "/etc/loki/loki.yml" + owner: root + group: root + mode: "0644" + + +- name: "Install requested Loki version" + block: + - name: "Check Loki version" + ansible.builtin.command: /opt/loki/loki -version + register: loki_version_check + changed_when: false + + - name: "Assert version correctness" + notify: "Restart the Loki daemon" + ansible.builtin.assert: + that: "loki_version in loki_version_check.stdout" + success_msg: "Expected Loki version available ({{ loki_version }})" + fail_msg: "Expected version '{{ loki_version }}'; available is '{{ loki_version_check.stdout }}'" + + rescue: + - name: "Install Loki if it is not present ({{ loki_version }})" + ansible.builtin.unarchive: + src: "https://github.com/grafana/loki/releases/download/v\ + {{ loki_version }}/loki-linux-amd64.zip" + dest: /opt/loki/ + remote_src: true + + - name: "Rename and set permissions for the Loki binary" + ansible.builtin.copy: + src: "/opt/loki/loki-linux-amd64" + dest: /opt/loki/loki + owner: root + group: root + mode: "0755" + remote_src: true + + - name: "Cleanup downloaded file" + ansible.builtin.file: + path: /opt/loki/loki-linux-amd64 + state: absent + + - name: "Install logcli" + ansible.builtin.unarchive: + src: "https://github.com/grafana/loki/releases/download/v\ + {{ loki_version }}/logcli-linux-amd64.zip" + dest: /usr/local/bin + remote_src: true + + - name: "Rename and set permissions for the Logcli binary" + ansible.builtin.copy: + src: "/usr/local/bin/logcli-linux-amd64" + dest: "/usr/local/bin/logcli" + owner: root + group: root + mode: "0755" + remote_src: true + + - name: "Cleanup downloaded file" + ansible.builtin.file: + path: /usr/local/bin/logcli-linux-amd64 + state: absent + +- name: "Template the systemd unit file" + notify: "Reload the Loki daemon configuration" + ansible.builtin.template: + src: templates/loki.service.j2 + dest: /etc/systemd/system/loki.service + owner: root + group: root + mode: "0755" + +- name: "Start and enable the Loki daemon" + ansible.builtin.systemd: + name: loki + state: started + enabled: true diff --git a/roles/loki/templates/loki.service.j2 b/roles/loki/templates/loki.service.j2 new file mode 100644 index 0000000..6cc23bc --- /dev/null +++ b/roles/loki/templates/loki.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=Loki service +After=network.target + +[Service] +Type=simple +User=root +ExecStart=/opt/loki/loki -config.file /etc/loki/loki.yml + +[Install] +WantedBy=multi-user.target diff --git a/roles/loki/templates/loki.yml.j2 b/roles/loki/templates/loki.yml.j2 new file mode 100644 index 0000000..8236f15 --- /dev/null +++ b/roles/loki/templates/loki.yml.j2 @@ -0,0 +1,83 @@ +auth_enabled: false + +server: + http_listen_port: {{ loki_port }} + # grpc_listen_port: 9096 + # log_level: debug + # grpc_server_max_concurrent_streams: 1000 + +common: + instance_addr: 127.0.0.1 + path_prefix: {{ loki_storage_path }} + storage: + filesystem: + chunks_directory: {{ loki_storage_path }}/chunks + rules_directory: {{ loki_storage_path }}/rules + replication_factor: 1 + ring: + kvstore: + store: inmemory + +# ingester: +# lifecycler: +# address: 127.0.0.1 +# ring: +# kvstore: +# store: inmemory +# replication_factor: 1 +# final_sleep: 0s +# chunk_idle_period: 5m +# chunk_retain_period: 30s +# max_transfer_retries: 0 + +schema_config: + configs: + - from: 2020-10-24 + store: tsdb + object_store: filesystem + schema: v13 + index: + prefix: index_ + period: 24h + +pattern_ingester: + enabled: true + metric_aggregation: + loki_address: localhost:3100 + +# storage_config: +# boltdb: +# directory: {{ loki_storage_path }}/index + +# filesystem: +# directory: {{ loki_storage_path }}/chunks + +# ruler: +# alertmanager_url: http://localhost:9093 + +query_range: + results_cache: + cache: + embedded_cache: + enabled: true + max_size_mb: 100 + +frontend: + encoding: protobuf + +# querier: +# engine: +# enable_multi_variant_queries: true + +limits_config: + metric_aggregation_enabled: true + +# chunk_store_config: +# max_look_back_period: 0s + +# table_manager: +# retention_deletes_enabled: false +# retention_period: 0s + +analytics: + reporting_enabled: false diff --git a/roles/loki/templates/loki_test.yml.j2 b/roles/loki/templates/loki_test.yml.j2 new file mode 100644 index 0000000..954f214 --- /dev/null +++ b/roles/loki/templates/loki_test.yml.j2 @@ -0,0 +1,45 @@ +auth_enabled: false + +server: + http_listen_port: 3200 + +ingester: + lifecycler: + address: 127.0.0.1 + ring: + kvstore: + store: inmemory + replication_factor: 1 + final_sleep: 0s + chunk_idle_period: 5m + chunk_retain_period: 30s + max_transfer_retries: 0 + +schema_config: + configs: + - from: 2018-04-15 + store: boltdb + object_store: filesystem + schema: v11 + index: + prefix: index_ + period: 168h + +storage_config: + boltdb: + directory: /data/loki/index + + filesystem: + directory: /data/loki/chunks + +limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 168h + +chunk_store_config: + max_look_back_period: 0s + +table_manager: + retention_deletes_enabled: false + retention_period: 0s diff --git a/roles/loki/vars/main.yml b/roles/loki/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/loki/vars/main.yml @@ -0,0 +1 @@ +---