Start DISCTL-WP-0002: policies, registers, runbooks, playbooks

Expand AssetRegister and DataRegister with T0/T4 stack assets.
Add ResiliencePolicy, PanicSheet, full-server-loss runbook, and five
incident playbooks. Update README with mirror status. Mark T02-T05,
T07-T08 done; T01 and T06 in progress.
This commit is contained in:
tegwick 2026-07-07 20:04:54 +02:00
parent 4288ad21a9
commit d011073e16
13 changed files with 814 additions and 29 deletions

View file

@ -0,0 +1,126 @@
# Restore Runbook: Full Server Loss
**Trigger:** disk failure, VPS deletion, hardware loss, unrecoverable OS corruption.
**RTO target:** ≤ 1 day full recovery; ≤ 48h for code/content/control plane.
**Owner:** Bernd
Do **not** restore into a compromised machine. This runbook assumes hardware
loss, not active breach (see `IncidentPlaybooks/ransomware.md` for breach).
---
## Prerequisites
- [ ] Password-manager copy of age backup keys
- [ ] OpenBao unseal material (if restoring railiance01 secrets)
- [ ] Nextcloud admin or local backup cache access
- [ ] IONOS DNS access
- [ ] `warden sign` SSH access to new host
- [ ] This repo cloned (from mirror once T01 complete; until then: any copy)
---
## Phase 1 — Provision clean host
1. Provision new Ubuntu server (or recover WSL2 workstation for dev lane only).
2. Apply SSH hardening via Ansible (`railiance-infra`).
3. Install tooling: `age`, `docker`, `k3s`, `helm`, `kubectl`, `ansible`.
4. Record new host identity in `AssetRegister.yaml` after recovery.
---
## Phase 2 — Secret recovery
1. Retrieve OpenBao unseal keys from sealed recovery vault (password manager).
2. If railiance01: follow `railiance-platform` OpenBao deploy/unseal runbooks.
3. Retrieve backup upload credentials from OpenBao if re-wiring backup jobs.
4. **Do not** copy plaintext secrets into Git, chat, or State Hub.
---
## Phase 3 — Data restore (by lane)
### Dev workstation (bnt-lap001)
1. Download latest `db-*.sql.age` and `config-*.tar.gz.age` from Nextcloud.
2. `age -d -i ~/.config/age/railiance-backup.key -o dump.sql db-*.sql.age`
3. Restore PostgreSQL `custodian` database into `infra-postgres-1`.
4. Decrypt and unpack config tar to `$HOME`.
5. Verify: `bin/railiance preflight` exits 0.
Reference: `railiance-cluster/docs/backup-restore.md`
### railiance01 — S1 OS config (optional)
1. Decrypt `os-config-*.tar.gz.age` from `/opt/backup/railiance/infra/` (if disk survived)
or offsite copy when wired.
2. Restore files or re-apply Ansible playbooks (preferred).
### railiance01 — S2 k8s runtime
1. If rebuilding k3s: install k3s on clean host.
2. Decrypt `helm-values-*.tar.gz.age` — redeploy each release with saved values.
3. Decrypt `kubeconfig-*.yaml.age` if needed for admin access.
4. k3s `state.db` hot backup: prefer **redeploy from Git/Helm** over raw DB restore.
Reference: `railiance-cluster/tools/cmd/railiance-backup-s2`
### Gitea (coulombcore)
1. If coulombcore lost: provision host, install Gitea via Ansible.
2. Restore from latest `gitea dump` or git mirrors of critical repos.
3. Verify: clone `coulomb/disaster-control`, API health.
### Forgejo (railiance01)
1. If automated backup wired: download latest dump from Nextcloud.
2. Run `railiance-infra/tools/forgejo-restore-drill.sh` (adapt for production namespace).
3. Verify: `GET /api/v1/version`, org repos visible.
Evidence: `TestEvidence/restore-drill-2026-07-04-forgejo.md`
### Platform databases
Blocked until `BackupPickupQueue.md` items 34 close (platform tool missing).
---
## Phase 4 — Validate services
| Check | Command / endpoint |
| --- | --- |
| k3s nodes | `kubectl get nodes` |
| Forgejo health | `curl -fsS https://forgejo.coulomb.social/api/v1/version` |
| Gitea health | `curl -fsS https://gitea.coulomb.social/api/v1/version` |
| State Hub | `curl -fsS http://127.0.0.1:8000/state/summary` |
| Representative app | App-specific smoke (e.g. vergabe health endpoint) |
---
## Phase 5 — DNS cutover
1. Confirm all services healthy on new infrastructure.
2. Update IONOS A records per `PanicSheet.md` §5.
3. Wait for TTL propagation; verify externally (`dig @8.8.8.8`).
4. Monitor for 24h.
---
## Phase 6 — Evidence report
Write `TestEvidence/restore-drill-YYYY-MM-DD-full-server-loss.md`:
- Start/end times (RTO measured)
- Backup artifacts used (RPO achieved)
- Systems restored vs redeployed
- Issues and follow-up actions
- Update `AssetRegister.yaml` if host identities changed
---
## References
- `PanicSheet.md`
- `BackupPolicy.md`
- `AssetRegister.yaml`
- `RTO-RPO-Matrix.md`