From cb4f2672cad5d235f53c562ae080c9a5529ac9fc Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Fri, 12 Dec 2025 11:44:47 +0300 Subject: [PATCH] add prometheus role --- roles/prometheus/.ansible-lint | 17 ++++ roles/prometheus/.gitignore | 2 + roles/prometheus/.yamllint | 8 ++ roles/prometheus/README.md | 50 +++++++++++ roles/prometheus/conda.dev.yml | 11 +++ roles/prometheus/conda.prod.yml | 9 ++ roles/prometheus/defaults/main.yml | 7 ++ roles/prometheus/handlers/main.yml | 8 ++ roles/prometheus/meta/main.yml | 17 ++++ .../prometheus/molecule/default/converge.yml | 8 ++ .../prometheus/molecule/default/molecule.yml | 27 ++++++ .../default/prometheus/prometheus.yml | 14 ++++ .../default/prometheus/rules/alertrules.yml | 13 +++ roles/prometheus/molecule/default/verify.yml | 55 ++++++++++++ roles/prometheus/renovate.json | 6 ++ roles/prometheus/requirements.ci.txt | 6 ++ roles/prometheus/requirements.txt | 1 + roles/prometheus/requirements.yml | 3 + roles/prometheus/tasks/configure.yml | 23 +++++ roles/prometheus/tasks/install.yml | 84 +++++++++++++++++++ roles/prometheus/tasks/main.yml | 9 ++ .../templates/prometheus.service.j2 | 28 +++++++ roles/prometheus/vars/main.yml | 1 + 23 files changed, 407 insertions(+) create mode 100644 roles/prometheus/.ansible-lint create mode 100644 roles/prometheus/.gitignore create mode 100644 roles/prometheus/.yamllint create mode 100644 roles/prometheus/README.md create mode 100644 roles/prometheus/conda.dev.yml create mode 100644 roles/prometheus/conda.prod.yml create mode 100644 roles/prometheus/defaults/main.yml create mode 100644 roles/prometheus/handlers/main.yml create mode 100644 roles/prometheus/meta/main.yml create mode 100644 roles/prometheus/molecule/default/converge.yml create mode 100644 roles/prometheus/molecule/default/molecule.yml create mode 100644 roles/prometheus/molecule/default/prometheus/prometheus.yml create mode 100644 roles/prometheus/molecule/default/prometheus/rules/alertrules.yml create mode 100644 roles/prometheus/molecule/default/verify.yml create mode 100644 roles/prometheus/renovate.json create mode 100644 roles/prometheus/requirements.ci.txt create mode 100644 roles/prometheus/requirements.txt create mode 100644 roles/prometheus/requirements.yml create mode 100644 roles/prometheus/tasks/configure.yml create mode 100644 roles/prometheus/tasks/install.yml create mode 100644 roles/prometheus/tasks/main.yml create mode 100644 roles/prometheus/templates/prometheus.service.j2 create mode 100644 roles/prometheus/vars/main.yml diff --git a/roles/prometheus/.ansible-lint b/roles/prometheus/.ansible-lint new file mode 100644 index 0000000..3a5bc7d --- /dev/null +++ b/roles/prometheus/.ansible-lint @@ -0,0 +1,17 @@ +--- +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/ + - molecule/default/prometheus/ diff --git a/roles/prometheus/.gitignore b/roles/prometheus/.gitignore new file mode 100644 index 0000000..8cd0df3 --- /dev/null +++ b/roles/prometheus/.gitignore @@ -0,0 +1,2 @@ +.vscode +.idea \ No newline at end of file diff --git a/roles/prometheus/.yamllint b/roles/prometheus/.yamllint new file mode 100644 index 0000000..611db54 --- /dev/null +++ b/roles/prometheus/.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/prometheus/README.md b/roles/prometheus/README.md new file mode 100644 index 0000000..d8894ce --- /dev/null +++ b/roles/prometheus/README.md @@ -0,0 +1,50 @@ +genlab.prometheus +========= + +This ansible role installs [Prometheus](https://github.com/prometheus/prometheus) from binary distribution. Prometheus is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts when specified conditions are observed. + +Prometheus configuration files and rules should be placed in separate directories in the source. They must have a `*.yml` suffix. You'll need to manually specify the paths to your rule files in the main Prometheus configuration file (prometheus.yml) on the target machine + +Requirements +------------ + +None + +Role Variables +-------------- +``` +prometheus_version: 3.2.1 # prometheus version +prometheus_dir: "/etc/prometheus" # where to install prometheus +prometheus_user: prometheus # user name +prometheus_group: prometheus # groups name +config_dir: "/etc/prometheus/conf" # where to place prometheus config +db_dir: "/var/lib/prometheus" # where to store prometheus db +config_source_dir: prometheus # path to config files on source +alertrules_source_dir: prometheus/rules # path to rule files on source +``` + +Dependencies +------------ + +None + +Example Playbook +---------------- + +```yaml +roles: + - role: genlab.prometheus + config_source_dir: mydir/configs + alertrules_source_dir: mydir/configs/rules + prometheus_version: 3.2.1 +``` + +License +------- + +BSD + +Author Information +------------------ + +corvus-migratorius@proton.me diff --git a/roles/prometheus/conda.dev.yml b/roles/prometheus/conda.dev.yml new file mode 100644 index 0000000..fb974b7 --- /dev/null +++ b/roles/prometheus/conda.dev.yml @@ -0,0 +1,11 @@ +--- +name: ansible-role-template +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - actionlint + - pip: + - -r requirements.txt + - -r requirements.ci.txt diff --git a/roles/prometheus/conda.prod.yml b/roles/prometheus/conda.prod.yml new file mode 100644 index 0000000..d6d12d6 --- /dev/null +++ b/roles/prometheus/conda.prod.yml @@ -0,0 +1,9 @@ +--- +name: ansible-role-template +channels: + - conda-forge +dependencies: + - python~=3.12.0 + - pip>=24.2 + - pip: + - -r requirements.txt diff --git a/roles/prometheus/defaults/main.yml b/roles/prometheus/defaults/main.yml new file mode 100644 index 0000000..891c50d --- /dev/null +++ b/roles/prometheus/defaults/main.yml @@ -0,0 +1,7 @@ +--- +prometheus_version: 3.2.1 +prometheus_dir: "/etc/prometheus" +prometheus_user: prometheus +prometheus_group: prometheus +config_dir: "/etc/prometheus/conf" +db_dir: "/var/lib/prometheus" diff --git a/roles/prometheus/handlers/main.yml b/roles/prometheus/handlers/main.yml new file mode 100644 index 0000000..29ac016 --- /dev/null +++ b/roles/prometheus/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: "(Re)start Prometheus service" + become: true + ansible.builtin.systemd: + name: prometheus.service + state: restarted + enabled: true + daemon_reload: true diff --git a/roles/prometheus/meta/main.yml b/roles/prometheus/meta/main.yml new file mode 100644 index 0000000..b65335e --- /dev/null +++ b/roles/prometheus/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + role_name: "prometheus" + namespace: genlab + author: "Alexander Gorelyshev" + company: "Genlab, LLC" + description: "" + license: "MIT" + min_ansible_version: "2.1" + + platforms: + - name: "Ubuntu" + versions: [ "focal", "jammy", "noble" ] + + galaxy_tags: [ ] + +dependencies: [] diff --git a/roles/prometheus/molecule/default/converge.yml b/roles/prometheus/molecule/default/converge.yml new file mode 100644 index 0000000..1d9f0cf --- /dev/null +++ b/roles/prometheus/molecule/default/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + + roles: + - role: genlab.prometheus + config_source_dir: prometheus + alertrules_source_dir: prometheus/rules diff --git a/roles/prometheus/molecule/default/molecule.yml b/roles/prometheus/molecule/default/molecule.yml new file mode 100644 index 0000000..d82158e --- /dev/null +++ b/roles/prometheus/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy + +driver: + name: docker + +platforms: + - name: ubuntu + image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2404}-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/prometheus/molecule/default/prometheus/prometheus.yml b/roles/prometheus/molecule/default/prometheus/prometheus.yml new file mode 100644 index 0000000..9368ee3 --- /dev/null +++ b/roles/prometheus/molecule/default/prometheus/prometheus.yml @@ -0,0 +1,14 @@ +--- +global: + scrape_interval: 15s + evaluation_interval: 15s + +rule_files: + - /etc/prometheus/conf/alertules.yml + # - "first.rules" + # - "second.rules" + +scrape_configs: + - job_name: prometheus + static_configs: + - targets: ['localhost:9090'] \ No newline at end of file diff --git a/roles/prometheus/molecule/default/prometheus/rules/alertrules.yml b/roles/prometheus/molecule/default/prometheus/rules/alertrules.yml new file mode 100644 index 0000000..f85947d --- /dev/null +++ b/roles/prometheus/molecule/default/prometheus/rules/alertrules.yml @@ -0,0 +1,13 @@ +groups: +- name: example + labels: + team: myteam + rules: + - alert: HighRequestLatency + expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5 + for: 10m + keep_firing_for: 5m + labels: + severity: page + annotations: + summary: High request latency \ No newline at end of file diff --git a/roles/prometheus/molecule/default/verify.yml b/roles/prometheus/molecule/default/verify.yml new file mode 100644 index 0000000..350252a --- /dev/null +++ b/roles/prometheus/molecule/default/verify.yml @@ -0,0 +1,55 @@ +--- +- name: Verify + hosts: all + gather_facts: false + any_errors_fatal: true + + tasks: + + - name: "Include default vars" + ansible.builtin.include_vars: + dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/" + extensions: [ 'yml' ] + + - name: "Check if Prometheus is installed" + changed_when: false + ansible.builtin.command: "prometheus --version" + register: prom_installed_version + + - name: "Check Prometheus version" + ansible.builtin.assert: + that: "prom_installed_version.stdout is regex('{{ prometheus_version }}')" + success_msg: "Prometheus version {{ prometheus_version }} is installed and working" + fail_msg: "Prometheus version {{ prometheus_version }} is not installed or not working correctly" + + # kics-scan ignore-block + - name: "Check if Prometheus is reachable" + ansible.builtin.uri: + url: "http://localhost:9090/-/healthy" + return_content: true + status_code: 200 + method: GET + body_format: json + register: prom_health + + - name: "Debug Prometheus health status" + ansible.builtin.assert: + that: "prom_health.content | trim == 'Prometheus Server is Healthy.'" + success_msg: "Prometheus is healthy" + fail_msg: "Prometheus is not healthy" + + # kics-scan ignore-block + - name: "Check if Prometheus is ready" + ansible.builtin.uri: + url: "http://localhost:9090/-/ready" + return_content: true + status_code: 200 + method: GET + body_format: json + register: prom_ready + + - name: "Debug Prometheus readiness status" + ansible.builtin.assert: + that: "prom_ready.content | trim == 'Prometheus Server is Ready.'" + success_msg: "Prometheus is ready" + fail_msg: "Prometheus is not ready" diff --git a/roles/prometheus/renovate.json b/roles/prometheus/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/roles/prometheus/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/roles/prometheus/requirements.ci.txt b/roles/prometheus/requirements.ci.txt new file mode 100644 index 0000000..f99c76a --- /dev/null +++ b/roles/prometheus/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/prometheus/requirements.txt b/roles/prometheus/requirements.txt new file mode 100644 index 0000000..92f8677 --- /dev/null +++ b/roles/prometheus/requirements.txt @@ -0,0 +1 @@ +ansible~=11.3.0 diff --git a/roles/prometheus/requirements.yml b/roles/prometheus/requirements.yml new file mode 100644 index 0000000..3d5f1cd --- /dev/null +++ b/roles/prometheus/requirements.yml @@ -0,0 +1,3 @@ +# requirements file +--- +collections: [] diff --git a/roles/prometheus/tasks/configure.yml b/roles/prometheus/tasks/configure.yml new file mode 100644 index 0000000..8e31514 --- /dev/null +++ b/roles/prometheus/tasks/configure.yml @@ -0,0 +1,23 @@ +--- +- name: "Copy config file" + notify: "(Re)start Prometheus service" + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ config_dir }}/{{ item | basename }}" + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + mode: "0660" + with_fileglob: + - "{{ config_source_dir }}/*.yml" + +- name: "Copy alert rules" + notify: "(Re)start Prometheus service" + when: alertrules_source_dir is defined + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ config_dir }}/{{ item | basename }}" + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + mode: "0660" + with_fileglob: + - "{{ alertrules_source_dir }}/*.yml" diff --git a/roles/prometheus/tasks/install.yml b/roles/prometheus/tasks/install.yml new file mode 100644 index 0000000..05ebb7a --- /dev/null +++ b/roles/prometheus/tasks/install.yml @@ -0,0 +1,84 @@ +--- +- name: "Create Prometheus system group" + ansible.builtin.group: + name: "{{ prometheus_group }}" + system: true + state: present + +- name: "Create Prometheus system user" + ansible.builtin.user: + name: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + system: true + shell: "/sbin/nologin" + create_home: false + state: present + +- name: "Install prometheus from binary" + block: + - name: "Check Prometheus version" + changed_when: false + ansible.builtin.command: + cmd: "prometheus --version" + register: prometheus_ver + + - name: "Assert version correctness" + ansible.builtin.assert: + that: "prometheus_ver.stdout is regex('{{ prometheus_version }}')" + success_msg: "prometheus version {{ prometheus_version }} is installed and working" + fail_msg: "prometheus version {{ prometheus_version }} is not installed or not working correctly" + + rescue: + - name: "Create prometheus directories {{ item }}" + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + mode: "0755" + with_items: + - "{{ config_dir }}" + - "{{ prometheus_dir }}" + - "{{ db_dir }}" + + - name: "Download Prometheus binary" + ansible.builtin.get_url: + url: "https://github.com/prometheus/prometheus/releases/download/v{{ prometheus_version }}/prometheus-{{ prometheus_version }}.linux-amd64.tar.gz" + dest: "/tmp/prometheus-{{ prometheus_version }}.linux-amd64.tar.gz" + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + mode: "0644" + + - name: "Unpack Prometheus binaries" + notify: "(Re)start Prometheus service" + ansible.builtin.unarchive: + src: "/tmp/prometheus-{{ prometheus_version }}.linux-amd64.tar.gz" + dest: "{{ prometheus_dir }}" + creates: "{{ prometheus_dir }}/prometheus-{{ prometheus_version }}.linux-amd64" + remote_src: true + + - name: "Cleanup downloaded file" + ansible.builtin.file: + path: "/tmp/prometheus-{{ prometheus_version }}.linux-amd64.tar.gz" + state: absent + + - name: "Move official prometheus and promtool binaries" + ansible.builtin.copy: + src: "{{ prometheus_dir }}/prometheus-{{ prometheus_version }}.linux-amd64/{{ item }}" + dest: "/usr/local/bin/{{ item }}" + mode: "0755" + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + remote_src: true + with_items: + - prometheus + - promtool + +- name: "Create systemd service unit" + notify: "(Re)start Prometheus service" + ansible.builtin.template: + src: prometheus.service.j2 + dest: /etc/systemd/system/prometheus.service + owner: "{{ prometheus_user }}" + group: "{{ prometheus_group }}" + mode: "0660" diff --git a/roles/prometheus/tasks/main.yml b/roles/prometheus/tasks/main.yml new file mode 100644 index 0000000..43bcfba --- /dev/null +++ b/roles/prometheus/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: "Install Prometheus from binary" + ansible.builtin.include_tasks: install.yml + +- name: "Configure and add alert rules" + ansible.builtin.include_tasks: configure.yml + +- name: "Flush handlers" + ansible.builtin.meta: "flush_handlers" diff --git a/roles/prometheus/templates/prometheus.service.j2 b/roles/prometheus/templates/prometheus.service.j2 new file mode 100644 index 0000000..839c5f4 --- /dev/null +++ b/roles/prometheus/templates/prometheus.service.j2 @@ -0,0 +1,28 @@ +[Unit] +Description=Prometheus +Wants=network-online.target +After=network-online.target +Documentation="https://prometheus.io/" + +[Service] +User=prometheus +Group=prometheus +Type=simple +ExecStart=/usr/local/bin/prometheus \ + --config.file {{ config_dir }}/prometheus.yml \ + --storage.tsdb.path {{ db_dir }} \ + --storage.tsdb.retention.time=30d + +# Security hardening +ReadWritePaths={{ db_dir }} +ProtectSystem=strict +NoNewPrivileges=true +PrivateTmp=true +ProtectKernelModules=true +ProtectControlGroups=true +ProtectKernelTunables=true +ProtectClock=yes +RestrictSUIDSGID=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/roles/prometheus/vars/main.yml b/roles/prometheus/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/prometheus/vars/main.yml @@ -0,0 +1 @@ +---