247 lines
8.7 KiB
YAML

---
# roles/monitoring_stack/tasks/main.yml
# Deploy and configure the complete monitoring stack on Watchtower
- name: Resolve focused deployment selection
ansible.builtin.set_fact:
monitoring_selected_services: >-
{{
[monitoring_focus_service]
if (monitoring_focus_mode | bool)
else [
'traefik-kop',
'prometheus',
'grafana',
'uptime-kuma',
'node-exporter',
'watchtower-cadvisor',
'blackbox-exporter',
'dozzle',
'authentik-outpost-dozzle',
'loki',
'promtail',
'portainer'
]
}}
- name: Show selected monitoring services
ansible.builtin.debug:
msg:
- "Focus mode: {{ monitoring_focus_mode | bool }}"
- "Selected service set: {{ monitoring_selected_services }}"
- name: Validate supported focused service target
ansible.builtin.assert:
that:
- monitoring_focus_service in ['prometheus', 'node-exporter', 'watchtower-cadvisor', 'blackbox-exporter']
fail_msg: >-
Unsupported monitoring_focus_service='{{ monitoring_focus_service }}'.
Supported focused services: prometheus, node-exporter, watchtower-cadvisor, blackbox-exporter.
when: monitoring_focus_mode | bool
- name: Validate Grafana admin password is defined
ansible.builtin.assert:
that:
- grafana_admin_password is defined
- grafana_admin_password | length > 0
- grafana_admin_password not in ['change-me-now', 'changeme', 'admin', 'password']
fail_msg: "grafana_admin_password must be defined in inventory with a secure value (not a default placeholder)"
success_msg: "Grafana password validation passed"
when: "'grafana' in monitoring_selected_services"
- name: Validate Authentik outpost token is defined
ansible.builtin.assert:
that:
- authentik_outpost_dozzle_token is defined
- authentik_outpost_dozzle_token | trim | length > 0
- authentik_outpost_dozzle_token != 'your-authentik-token-here'
fail_msg: "authentik_outpost_dozzle_token is required (vault or environment) and cannot be empty"
success_msg: "Authentik outpost token validation passed"
when: monitoring_enable_authentik_outpost | bool
and 'authentik-outpost-dozzle' in monitoring_selected_services
no_log: true
- name: Create monitoring directories
become: true
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0755'
loop:
- "{{ stack_dir }}"
- "{{ stack_dir }}/prometheus-data"
- "{{ stack_dir }}/prometheus-config"
- "{{ stack_dir }}/prometheus-config/alerts"
- "{{ stack_dir }}/grafana-data"
- "{{ stack_dir }}/grafana-provisioning"
- "{{ stack_dir }}/grafana-provisioning/datasources"
- "{{ stack_dir }}/grafana-provisioning/plugins"
- "{{ stack_dir }}/grafana-provisioning/alerting"
- "{{ stack_dir }}/grafana-provisioning/dashboards"
- "{{ stack_dir }}/grafana-provisioning/dashboards/homelab"
- "{{ stack_dir }}/uptime-kuma-data"
- "{{ stack_dir }}/dozzle-data"
- "{{ stack_dir }}/loki-data"
- "{{ stack_dir }}/loki-config"
- "{{ stack_dir }}/promtail-data"
- "{{ stack_dir }}/promtail-config"
- "{{ stack_dir }}/blackbox-config"
- "{{ stack_dir }}/portainer-data"
- "{{ pve_exporter_config_dir }}"
- name: Render Prometheus configuration
ansible.builtin.template:
src: prometheus.yml.j2
dest: "{{ stack_dir }}/prometheus-config/prometheus.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Prometheus alert rules
ansible.builtin.template:
src: alert-rules.yml.j2
dest: "{{ stack_dir }}/prometheus-config/alerts/homelab.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana datasource provisioning
ansible.builtin.template:
src: grafana-datasource.yml.j2
dest: "{{ stack_dir }}/grafana-provisioning/datasources/prometheus.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana dashboard provider provisioning
ansible.builtin.template:
src: grafana-dashboard-provider.yml.j2
dest: "{{ stack_dir }}/grafana-provisioning/dashboards/homelab-provider.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana homelab overview dashboard
ansible.builtin.template:
src: grafana-homelab-overview.json.j2
dest: "{{ stack_dir }}/grafana-provisioning/dashboards/homelab/homelab-overview.json"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana swarm health dashboard
ansible.builtin.template:
src: grafana-swarm-health.json.j2
dest: "{{ stack_dir }}/grafana-provisioning/dashboards/homelab/swarm-health.json"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana blackbox reachability dashboard
ansible.builtin.template:
src: grafana-blackbox-reachability.json.j2
dest: "{{ stack_dir }}/grafana-provisioning/dashboards/homelab/blackbox-reachability.json"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Grafana monitoring coverage dashboard
ansible.builtin.template:
src: grafana-monitoring-coverage.json.j2
dest: "{{ stack_dir }}/grafana-provisioning/dashboards/homelab/monitoring-coverage.json"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Loki configuration
ansible.builtin.template:
src: loki-config.yml.j2
dest: "{{ stack_dir }}/loki-config/loki-config.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Promtail configuration
ansible.builtin.template:
src: promtail-config.yml.j2
dest: "{{ stack_dir }}/promtail-config/promtail-config.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render Blackbox exporter configuration
ansible.builtin.template:
src: blackbox.yml.j2
dest: "{{ stack_dir }}/blackbox-config/blackbox.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render pve-exporter configuration
ansible.builtin.template:
src: pve-exporter.yml.j2
dest: "{{ pve_exporter_config_dir }}/pve.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0600'
no_log: true
notify: Restart monitoring stack
- name: Render watchtower compose specification
ansible.builtin.template:
src: "{{ 'docker-compose.focus.j2' if (monitoring_focus_mode | bool) else 'docker-compose.yml.j2' }}"
dest: "{{ stack_dir }}/docker-compose.yml"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0644'
notify: Restart monitoring stack
- name: Render watchtower environment file
ansible.builtin.template:
src: env.j2
dest: "{{ stack_dir }}/.env"
owner: "{{ chester_user }}"
group: "{{ chester_user }}"
mode: '0600'
no_log: true
notify: Restart monitoring stack
- name: Launch watchtower monitoring stack
community.docker.docker_compose_v2:
project_src: "{{ stack_dir }}"
state: present
pull: always
docker_host: "unix:///run/user/1000/docker.sock"
remove_orphans: false
register: compose_result
- name: Display deployed services
ansible.builtin.debug:
msg:
- "🎯 Monitoring Stack Deployed Successfully!"
- " Selected services: {{ monitoring_selected_services }}"
- " 📊 Prometheus: http://{{ watchtower_ip }}:{{ prometheus_host_port }}"
- " 📈 Grafana: {{ 'enabled' if 'grafana' in monitoring_selected_services else 'skipped in focus mode' }}"
- " ✅ Uptime Kuma: {{ 'enabled' if 'uptime-kuma' in monitoring_selected_services else 'skipped in focus mode' }}"
- " 📋 Dozzle: {{ 'enabled' if 'dozzle' in monitoring_selected_services else 'skipped in focus mode' }}"
- " 📝 Loki: {{ 'enabled' if 'loki' in monitoring_selected_services else 'skipped in focus mode' }}"
- " 🌐 Blackbox: {{ 'enabled' if 'blackbox-exporter' in monitoring_selected_services else 'skipped in focus mode' }}"
- ""
- "🔍 Next Steps:"
- " 1. Access Grafana and verify Prometheus + Loki datasources"
- " 2. Review the '{{ grafana_dashboards_folder }}' dashboard folder"
- " 3. Configure Uptime Kuma health checks"