Files
cluster-knaster/platform/proxmox/ansible/roles/infra-stack/tasks/main.yml
T
Robert RappandClaude Opus 5.5 4a1bda3409
ci / test (push) Failing after 22s
Merge main in plan/aufbau-2026-10-12: KNOW-Analyse, Ontologie, cpu_roles
main (bis 13.10.) enthielt eine parallele Fassung von Task 0.4 (c81e372) sowie
KNOW-Befunde und die Ontologie. Konflikte zugunsten des Plan-Branches gelöst
(ausgerollter Stand); übernommen aus main: Ontologie (core/src/knaster/ontology,
ontology/, Tests, Router-Image), KNOW-Doku, cpu_roles im Placement samt
Kennzeichnung von pve61 und gode-pc-05/06 im Inventar und Test.
infra-stack kopiert jetzt auch ontology/ nach infra (Router-Build braucht es).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:23:22 +02:00

184 lines
6.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Compose-Stack infra: Router, TTS, Postgres, Prometheus, Alertmanager, Grafana, pve-exporter, node-exporter.
# Idempotent: Geheimnisse nur anlegen, wenn sie fehlen; compose up ändert nur, was sich geändert hat.
- name: Werkzeuge
ansible.builtin.apt:
name: [rsync, openssl, curl]
state: present
update_cache: true
cache_valid_time: 3600
- name: Verzeichnisse
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
mode: "{{ item.mode }}"
loop:
- {path: /opt/knaster, mode: "0755"}
- {path: "{{ infra_repo_dir }}", mode: "0755"}
- {path: "{{ infra_state_dir }}", mode: "0700"}
- {path: "{{ infra_state_dir }}/secrets", mode: "0700"}
- {path: "{{ infra_state_dir }}/secrets/k3s", mode: "0755"}
# Nur die Teile, die Build und Konfiguration brauchen. Nie .git, .venv, tofu-State oder .env-Dateien.
- name: Repo-Auszug von ops abgleichen
ansible.posix.synchronize:
src: "{{ infra_repo_src }}/"
dest: "{{ infra_repo_dir }}/"
delete: true
rsync_opts:
# Der Clone auf ops ist teils 0600/0700; Container-Benutzer (nobody, grafana, knaster) müssen lesen können
- "--chmod=go+rX,go-w"
- "--exclude=__pycache__"
- "--exclude=.pytest_cache"
- "--exclude=*.egg-info"
- "--exclude=.env"
- "--exclude=secrets/"
- "--include=/core/***"
- "--include=/config/***"
- "--include=/catalog/***"
- "--include=/skills/***"
- "--include=/ontology/***" # Router-Image kopiert ontology/ (KNASTER_ONTOLOGY)
- "--include=/sites/***"
- "--include=/deploy/***"
- "--exclude=*"
- name: Einstellungen in .env
ansible.builtin.lineinfile:
path: "{{ infra_state_dir }}/.env"
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
create: true
mode: "0600"
loop: "{{ infra_settings | dict2items }}"
# Gibt nur Namen aus, nie Werte
- name: Fehlende Geheimnisse im Container erzeugen
ansible.builtin.shell: |
set -eu
umask 077
f={{ infra_state_dir }}/.env
for k in {{ infra_secrets | join(' ') }}; do
grep -q "^$k=" "$f" || { echo "$k=$(openssl rand -hex 24)" >> "$f"; echo "neu: $k"; }
done
chmod 0600 "$f"
args:
executable: /bin/bash
register: secrets_gen
changed_when: "'neu:' in secrets_gen.stdout"
- name: Router-Token für Alertmanager (= KNASTER_API_TOKEN, lesbar für nobody im Container)
ansible.builtin.shell: |
set -eu
umask 077
cd {{ infra_state_dir }}
v=$(sed -n 's/^KNASTER_API_TOKEN=//p' .env)
t=secrets/router_token
if [ ! -f "$t" ] || [ "$(cat "$t")" != "$v" ]; then printf '%s' "$v" > "$t"; echo geändert; fi
chown 65534:65534 "$t"
chmod 0400 "$t"
args:
executable: /bin/bash
register: router_token
changed_when: "'geändert' in router_token.stdout"
no_log: true
- name: Proxmox-Lese-Token für den pve-exporter
ansible.builtin.copy:
src: "{{ infra_pve_exporter_env }}"
dest: "{{ infra_state_dir }}/secrets/pve-exporter.env"
mode: "0600"
no_log: true
# Task 6.5: Token des ServiceAccounts prometheus-infra und CA des Clusters (von playbooks/monitoring-k3s.yml
# auf ops abgelegt). Lesbar für nobody (Prometheus im Container). Fehlen sie, bleiben die k3s-Jobs down.
- name: k3s-Zugang für Prometheus vorhanden? (auf ops)
ansible.builtin.stat:
path: "{{ item }}"
loop: ["{{ infra_k3s_token }}", "{{ infra_k3s_ca }}"]
delegate_to: localhost
register: k3s_access
- name: k3s-Zugang für Prometheus kopieren
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ infra_state_dir }}/secrets/k3s/{{ item.dest }}"
owner: "65534"
group: "65534"
mode: "0400"
loop:
- {src: "{{ infra_k3s_token }}", dest: token}
- {src: "{{ infra_k3s_ca }}", dest: ca.crt}
loop_control:
label: "{{ item.dest }}"
when: k3s_access.results | map(attribute='stat.exists') | min
no_log: true
- name: file_sd-Ziele
ansible.builtin.include_tasks: targets.yml
# HA-Umzug: Nach zfs receive liefert der Zielknoten für früher gemappte Dateien veralteten Seiten-Cache
# (12.10.2026 belegt). Vor jedem Docker-Start den Cache dieses Containers verwerfen. BETRIEB.md Abschnitt 7.
- name: Schutz gegen veralteten Seiten-Cache – Skript
ansible.builtin.copy:
src: knaster-drop-stale-cache.py
dest: /usr/local/sbin/knaster-drop-stale-cache
mode: "0755"
- name: Schutz gegen veralteten Seiten-Cache – systemd-Dienst vor containerd/docker
ansible.builtin.copy:
src: knaster-drop-stale-cache.service
dest: /etc/systemd/system/knaster-drop-stale-cache.service
mode: "0644"
register: dropcache_unit
- name: Schutz gegen veralteten Seiten-Cache – aktivieren
ansible.builtin.systemd:
name: knaster-drop-stale-cache.service
enabled: true
daemon_reload: "{{ dropcache_unit.changed }}"
- name: Stack bauen und starten
ansible.builtin.command: >
docker compose -p {{ infra_compose_project }} --env-file {{ infra_state_dir }}/.env
-f {{ infra_compose_file }} up -d --build --remove-orphans
register: compose_up
changed_when: compose_up.stderr is search('Container \S+\s+(Created|Recreated|Started)')
- name: Prometheus und Alertmanager laden geänderte Konfiguration (bind-mount, kein Neustart nötig)
ansible.builtin.command: "curl -fsS -m 10 -X POST http://127.0.0.1:{{ item }}/-/reload"
loop: [9090, 9093]
register: reload
retries: 15
delay: 4
until: reload.rc == 0
changed_when: false
- name: Grafana-Konto kiosk (Viewer) anlegen, Passwort aus .env
ansible.builtin.shell: |
set -eu
cd {{ infra_state_dir }}
A=$(sed -n 's/^GRAFANA_ADMIN_PASSWORD=//p' .env)
K=$(sed -n 's/^GRAFANA_KIOSK_PASSWORD=//p' .env)
umask 077
cfg=$(mktemp)
trap 'rm -f "$cfg"' EXIT
printf 'user = "admin:%s"\n' "$A" > "$cfg" # Passwort nicht in der Prozessliste
g() { curl -sS -K "$cfg" -H 'Content-Type: application/json' "$@"; }
for i in $(seq 60); do curl -fsS -m 3 http://127.0.0.1:3000/api/health >/dev/null 2>&1 && break; sleep 2; done
code=$(g -o /dev/null -w '%{http_code}' 'http://127.0.0.1:3000/api/users/lookup?loginOrEmail=kiosk')
if [ "$code" = 404 ]; then
printf '{"name":"Kiosk","login":"kiosk","password":"%s"}' "$K" \
| g -f -X POST --data @- http://127.0.0.1:3000/api/admin/users >/dev/null
echo angelegt
elif [ "$code" != 200 ]; then
echo "Grafana-API antwortet $code" >&2
exit 1
fi
id=$(g -f 'http://127.0.0.1:3000/api/users/lookup?loginOrEmail=kiosk' | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
g -f -X PATCH --data '{"role":"Viewer"}' "http://127.0.0.1:3000/api/org/users/$id" >/dev/null
args:
executable: /bin/bash
register: kiosk
changed_when: "'angelegt' in kiosk.stdout"
no_log: true