docs: rewrite README with structured overview and quick start guide
Replaces the minimal project description with a comprehensive README including a component overview table, quick start instructions, common Ansible operations, and links to detailed documentation. Aligns with Red Panda Approval™ standards.
This commit is contained in:
495
ansible/pplg/deploy.yml
Normal file
495
ansible/pplg/deploy.yml
Normal file
@@ -0,0 +1,495 @@
|
||||
---
|
||||
# PPLG - Consolidated Observability & Admin Stack for Prospero
|
||||
# PgAdmin, Prometheus, Loki, Grafana + HAProxy (TLS) + OAuth2-Proxy (Prometheus UI)
|
||||
# Red Panda Approved
|
||||
|
||||
- name: Deploy PPLG Stack
|
||||
hosts: ubuntu
|
||||
become: true
|
||||
tasks:
|
||||
- name: Check if host has pplg service
|
||||
ansible.builtin.set_fact:
|
||||
has_pplg_service: "{{'pplg' in services}}"
|
||||
|
||||
- name: Skip hosts without pplg service
|
||||
ansible.builtin.meta: end_host
|
||||
when: not has_pplg_service
|
||||
|
||||
# ===========================================================================
|
||||
# APT Repositories
|
||||
# ===========================================================================
|
||||
|
||||
- name: Add Grafana APT repository (Grafana + Loki)
|
||||
ansible.builtin.deb822_repository:
|
||||
name: grafana
|
||||
types: [deb]
|
||||
uris: https://apt.grafana.com
|
||||
suites: [stable]
|
||||
components: [main]
|
||||
signed_by: https://apt.grafana.com/gpg.key
|
||||
state: present
|
||||
|
||||
- name: Add PgAdmin APT repository
|
||||
ansible.builtin.deb822_repository:
|
||||
name: pgadmin4
|
||||
types: [deb]
|
||||
uris: https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/{{ansible_distribution_release}}
|
||||
suites: [pgadmin4]
|
||||
components: [main]
|
||||
signed_by: https://www.pgadmin.org/static/packages_pgadmin_org.pub
|
||||
state: present
|
||||
|
||||
# ===========================================================================
|
||||
# Package Installation
|
||||
# ===========================================================================
|
||||
|
||||
- name: Install PPLG packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- acl
|
||||
- haproxy
|
||||
- prometheus
|
||||
- loki
|
||||
- grafana
|
||||
- pgadmin4-web
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Stop and disable Apache (pulled in by pgadmin4-web)
|
||||
ansible.builtin.systemd:
|
||||
name: apache2
|
||||
state: stopped
|
||||
enabled: false
|
||||
|
||||
# ===========================================================================
|
||||
# Prometheus
|
||||
# ===========================================================================
|
||||
|
||||
- name: Fix Prometheus directory permissions
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/prometheus
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '750'
|
||||
recurse: true
|
||||
|
||||
- name: Create textfile collector directory
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/prometheus/node-exporter
|
||||
state: directory
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '750'
|
||||
|
||||
- name: Template prometheus.yml
|
||||
ansible.builtin.template:
|
||||
src: prometheus.yml.j2
|
||||
dest: /etc/prometheus/prometheus.yml
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '640'
|
||||
notify: restart prometheus
|
||||
|
||||
- name: Template alert_rules.yml
|
||||
ansible.builtin.template:
|
||||
src: alert_rules.yml.j2
|
||||
dest: /etc/prometheus/alert_rules.yml
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '640'
|
||||
notify: restart prometheus
|
||||
|
||||
- name: Create Prometheus systemd override directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/prometheus.service.d
|
||||
state: directory
|
||||
mode: '755'
|
||||
|
||||
- name: Enable remote write receiver
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/metrics2/ --web.console.templates=/etc/prometheus/consoles --web.console.libraries=/etc/prometheus/console_libraries --web.listen-address=0.0.0.0:9090 --web.external-url= --web.enable-remote-write-receiver
|
||||
dest: /etc/systemd/system/prometheus.service.d/override.conf
|
||||
mode: '644'
|
||||
notify: restart prometheus
|
||||
|
||||
- name: Start and enable Prometheus service
|
||||
ansible.builtin.systemd:
|
||||
name: prometheus
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
# ===========================================================================
|
||||
# Prometheus Alertmanager
|
||||
# ===========================================================================
|
||||
|
||||
- name: Install Alertmanager
|
||||
ansible.builtin.apt:
|
||||
name: prometheus-alertmanager
|
||||
state: present
|
||||
|
||||
- name: Create alertmanager configuration directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/alertmanager
|
||||
state: directory
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '750'
|
||||
|
||||
- name: Template alertmanager.yml
|
||||
ansible.builtin.template:
|
||||
src: alertmanager.yml.j2
|
||||
dest: /etc/alertmanager/alertmanager.yml
|
||||
owner: prometheus
|
||||
group: prometheus
|
||||
mode: '640'
|
||||
notify: restart alertmanager
|
||||
|
||||
- name: Start and enable Alertmanager service
|
||||
ansible.builtin.systemd:
|
||||
name: prometheus-alertmanager
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
# ===========================================================================
|
||||
# Loki
|
||||
# ===========================================================================
|
||||
|
||||
- name: Create loki group
|
||||
ansible.builtin.group:
|
||||
name: "{{loki_group}}"
|
||||
|
||||
- name: Create loki user
|
||||
ansible.builtin.user:
|
||||
name: "{{loki_user}}"
|
||||
comment: "{{loki_user}}"
|
||||
group: "{{loki_group}}"
|
||||
system: true
|
||||
|
||||
- name: Create loki directories
|
||||
ansible.builtin.file:
|
||||
path: "{{item}}"
|
||||
owner: "{{loki_user}}"
|
||||
group: "{{loki_group}}"
|
||||
state: directory
|
||||
mode: '750'
|
||||
loop:
|
||||
- "{{loki_data_dir}}"
|
||||
- "{{loki_config_dir}}"
|
||||
|
||||
- name: Template Loki configuration
|
||||
ansible.builtin.template:
|
||||
src: "{{loki_config_file}}.j2"
|
||||
dest: "{{loki_config_dir}}/{{loki_config_file}}"
|
||||
owner: "{{loki_user}}"
|
||||
group: "{{loki_group}}"
|
||||
mode: '550'
|
||||
notify: restart loki
|
||||
|
||||
- name: Enable and start Loki service
|
||||
ansible.builtin.systemd:
|
||||
name: loki
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
# ===========================================================================
|
||||
# Grafana
|
||||
# ===========================================================================
|
||||
|
||||
- name: Create dashboards directory
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/grafana/dashboards
|
||||
state: directory
|
||||
owner: grafana
|
||||
group: grafana
|
||||
mode: '750'
|
||||
|
||||
- name: Template Grafana main configuration
|
||||
ansible.builtin.template:
|
||||
src: "grafana.ini.j2"
|
||||
dest: "/etc/grafana/grafana.ini"
|
||||
owner: grafana
|
||||
group: grafana
|
||||
mode: '640'
|
||||
when: grafana_oauth_enabled | default(false)
|
||||
notify: restart grafana
|
||||
|
||||
- name: Enable and start Grafana service
|
||||
ansible.builtin.systemd:
|
||||
name: grafana-server
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
# ===========================================================================
|
||||
# PgAdmin (Gunicorn - no Apache)
|
||||
# ===========================================================================
|
||||
|
||||
- name: Create pgadmin group
|
||||
ansible.builtin.group:
|
||||
name: "{{pgadmin_group}}"
|
||||
system: true
|
||||
|
||||
- name: Create pgadmin user
|
||||
ansible.builtin.user:
|
||||
name: "{{pgadmin_user}}"
|
||||
comment: "PgAdmin Service"
|
||||
group: "{{pgadmin_group}}"
|
||||
system: true
|
||||
create_home: false
|
||||
shell: /usr/sbin/nologin
|
||||
|
||||
- name: Create PgAdmin directories
|
||||
ansible.builtin.file:
|
||||
path: "{{item}}"
|
||||
state: directory
|
||||
owner: "{{pgadmin_user}}"
|
||||
group: "{{pgadmin_group}}"
|
||||
mode: '750'
|
||||
loop:
|
||||
- "{{pgadmin_data_dir}}"
|
||||
- "{{pgadmin_data_dir}}/sessions"
|
||||
- "{{pgadmin_data_dir}}/storage"
|
||||
- "{{pgadmin_data_dir}}/certs"
|
||||
- "{{pgadmin_log_dir}}"
|
||||
|
||||
- name: Install gunicorn into PgAdmin venv
|
||||
ansible.builtin.command:
|
||||
cmd: /usr/pgadmin4/venv/bin/pip install gunicorn
|
||||
register: pip_gunicorn
|
||||
changed_when: "'Successfully installed' in pip_gunicorn.stdout"
|
||||
|
||||
- name: Initialize PgAdmin database
|
||||
ansible.builtin.command:
|
||||
cmd: /usr/pgadmin4/venv/bin/python3 /usr/pgadmin4/web/setup.py setup-db
|
||||
creates: "{{pgadmin_data_dir}}/pgadmin4.db"
|
||||
become_user: "{{pgadmin_user}}"
|
||||
|
||||
- name: Template PgAdmin local config
|
||||
ansible.builtin.template:
|
||||
src: config_local.py.j2
|
||||
dest: /usr/pgadmin4/web/config_local.py
|
||||
owner: "{{pgadmin_user}}"
|
||||
group: "{{pgadmin_group}}"
|
||||
mode: '640'
|
||||
notify: restart pgadmin
|
||||
|
||||
- name: Fetch Titania PostgreSQL SSL cert
|
||||
ansible.builtin.fetch:
|
||||
src: /etc/postgresql/17/main/ssl/server.crt
|
||||
dest: /tmp/titania-postgres-ca.crt
|
||||
flat: yes
|
||||
delegate_to: titania.incus
|
||||
when: "'titania.incus' in groups['ubuntu']"
|
||||
|
||||
- name: Copy Titania PostgreSQL SSL cert to PgAdmin
|
||||
ansible.builtin.copy:
|
||||
src: /tmp/titania-postgres-ca.crt
|
||||
dest: "{{pgadmin_data_dir}}/certs/titania-postgres-ca.crt"
|
||||
owner: "{{pgadmin_user}}"
|
||||
group: "{{pgadmin_group}}"
|
||||
mode: '0644'
|
||||
when: "'titania.incus' in groups['ubuntu']"
|
||||
|
||||
- name: Template PgAdmin systemd service
|
||||
ansible.builtin.template:
|
||||
src: pgadmin.service.j2
|
||||
dest: /etc/systemd/system/pgadmin.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: restart pgadmin
|
||||
|
||||
- name: Enable and start PgAdmin service
|
||||
ansible.builtin.systemd:
|
||||
name: pgadmin
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
# ===========================================================================
|
||||
# OAuth2-Proxy Sidecar (Prometheus UI)
|
||||
# ===========================================================================
|
||||
|
||||
- name: Create oauth2-proxy config directory
|
||||
ansible.builtin.file:
|
||||
path: "{{prometheus_oauth2_proxy_dir}}"
|
||||
owner: root
|
||||
group: root
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Download oauth2-proxy binary
|
||||
ansible.builtin.get_url:
|
||||
url: "https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v{{prometheus_oauth2_proxy_version}}/oauth2-proxy-v{{prometheus_oauth2_proxy_version}}.linux-amd64.tar.gz"
|
||||
dest: "/tmp/oauth2-proxy-v{{prometheus_oauth2_proxy_version}}.tar.gz"
|
||||
mode: '0644'
|
||||
|
||||
- name: Extract oauth2-proxy binary
|
||||
ansible.builtin.unarchive:
|
||||
src: "/tmp/oauth2-proxy-v{{prometheus_oauth2_proxy_version}}.tar.gz"
|
||||
dest: /tmp
|
||||
remote_src: true
|
||||
creates: "/tmp/oauth2-proxy-v{{prometheus_oauth2_proxy_version}}.linux-amd64/oauth2-proxy"
|
||||
|
||||
- name: Install oauth2-proxy binary
|
||||
ansible.builtin.copy:
|
||||
src: "/tmp/oauth2-proxy-v{{prometheus_oauth2_proxy_version}}.linux-amd64/oauth2-proxy"
|
||||
dest: /usr/local/bin/oauth2-proxy
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
remote_src: true
|
||||
|
||||
- name: Template oauth2-proxy configuration for Prometheus
|
||||
ansible.builtin.template:
|
||||
src: oauth2-proxy-prometheus.cfg.j2
|
||||
dest: "{{prometheus_oauth2_proxy_dir}}/oauth2-proxy.cfg"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0600'
|
||||
notify: restart oauth2-proxy-prometheus
|
||||
|
||||
- name: Template oauth2-proxy systemd service for Prometheus
|
||||
ansible.builtin.template:
|
||||
src: oauth2-proxy-prometheus.service.j2
|
||||
dest: /etc/systemd/system/oauth2-proxy-prometheus.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify:
|
||||
- reload systemd
|
||||
- restart oauth2-proxy-prometheus
|
||||
|
||||
- name: Enable and start OAuth2-Proxy for Prometheus
|
||||
ansible.builtin.systemd:
|
||||
name: oauth2-proxy-prometheus
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
# ===========================================================================
|
||||
# SSL Certificate Distribution (from Titania)
|
||||
# ===========================================================================
|
||||
|
||||
- name: Create haproxy group
|
||||
ansible.builtin.group:
|
||||
name: "{{pplg_haproxy_group}}"
|
||||
gid: "{{pplg_haproxy_gid}}"
|
||||
system: true
|
||||
|
||||
- name: Create haproxy user
|
||||
ansible.builtin.user:
|
||||
name: "{{pplg_haproxy_user}}"
|
||||
comment: "PPLG HAProxy"
|
||||
group: "{{pplg_haproxy_group}}"
|
||||
uid: "{{pplg_haproxy_uid}}"
|
||||
system: true
|
||||
|
||||
- name: Create HAProxy directories
|
||||
ansible.builtin.file:
|
||||
path: "{{item}}"
|
||||
state: directory
|
||||
owner: "{{pplg_haproxy_user}}"
|
||||
group: "{{pplg_haproxy_group}}"
|
||||
mode: '750'
|
||||
loop:
|
||||
- /etc/haproxy
|
||||
- /etc/haproxy/certs
|
||||
|
||||
- name: Fetch wildcard certificate from Titania
|
||||
ansible.builtin.fetch:
|
||||
src: /etc/haproxy/certs/ouranos.pem
|
||||
dest: /tmp/ouranos-haproxy.pem
|
||||
flat: yes
|
||||
delegate_to: titania.incus
|
||||
when: "'titania.incus' in groups['ubuntu']"
|
||||
|
||||
- name: Deploy wildcard certificate
|
||||
ansible.builtin.copy:
|
||||
src: /tmp/ouranos-haproxy.pem
|
||||
dest: "{{pplg_haproxy_cert_path}}"
|
||||
owner: "{{pplg_haproxy_user}}"
|
||||
group: "{{pplg_haproxy_group}}"
|
||||
mode: '0640'
|
||||
when: "'titania.incus' in groups['ubuntu']"
|
||||
|
||||
- name: Generate self-signed wildcard certificate (fallback)
|
||||
command: >
|
||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048
|
||||
-keyout {{pplg_haproxy_cert_path}}
|
||||
-out {{pplg_haproxy_cert_path}}
|
||||
-subj "/C=US/ST=State/L=City/O=Agathos/CN=*.{{pplg_haproxy_domain}}"
|
||||
-addext "subjectAltName=DNS:*.{{pplg_haproxy_domain}},DNS:{{pplg_haproxy_domain}}"
|
||||
when: "'titania.incus' not in groups['ubuntu']"
|
||||
args:
|
||||
creates: "{{pplg_haproxy_cert_path}}"
|
||||
|
||||
# ===========================================================================
|
||||
# HAProxy (TLS Termination)
|
||||
# ===========================================================================
|
||||
|
||||
- name: Template HAProxy configuration
|
||||
ansible.builtin.template:
|
||||
src: pplg-haproxy.cfg.j2
|
||||
dest: /etc/haproxy/haproxy.cfg
|
||||
owner: "{{pplg_haproxy_user}}"
|
||||
group: "{{pplg_haproxy_group}}"
|
||||
mode: "640"
|
||||
validate: haproxy -c -f %s
|
||||
notify: restart haproxy
|
||||
|
||||
- name: Enable and start HAProxy service
|
||||
ansible.builtin.systemd:
|
||||
name: haproxy
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
# ===========================================================================
|
||||
# Handlers
|
||||
# ===========================================================================
|
||||
handlers:
|
||||
- name: restart prometheus
|
||||
ansible.builtin.systemd:
|
||||
name: prometheus
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
|
||||
- name: restart alertmanager
|
||||
ansible.builtin.systemd:
|
||||
name: prometheus-alertmanager
|
||||
state: restarted
|
||||
|
||||
- name: restart loki
|
||||
ansible.builtin.systemd:
|
||||
name: loki
|
||||
state: restarted
|
||||
|
||||
- name: restart grafana
|
||||
ansible.builtin.systemd:
|
||||
name: grafana-server
|
||||
state: restarted
|
||||
|
||||
- name: restart pgadmin
|
||||
ansible.builtin.systemd:
|
||||
name: pgadmin
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
|
||||
- name: reload systemd
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
|
||||
- name: restart haproxy
|
||||
ansible.builtin.systemd:
|
||||
name: haproxy
|
||||
state: reloaded
|
||||
|
||||
- name: restart oauth2-proxy-prometheus
|
||||
ansible.builtin.systemd:
|
||||
name: oauth2-proxy-prometheus
|
||||
state: restarted
|
||||
Reference in New Issue
Block a user