Mono-repo for my server stack
Find a file
Rasmus Wejlgaard d4341550c6 Add ZFS management role: scrub scheduling and pool monitoring
- New zfs role with cron-based scrub scheduling for Linux and FreeBSD
- Weekly Sunday scrubs at noon (matching existing manual crons)
- Add zfs_hosts inventory group with london-a and london-b
- Configure zfs_pools per host: zroot (london-a), hdd (london-b)
- Add Prometheus alert rules for degraded/faulted/offline pools
- Add zfs.yml playbook for targeted deploys

Captures the previously untracked scrub cron on london-a and
re-enables the commented-out scrub on london-b.

Refs: PESO-93
2026-03-29 15:09:54 +00:00
.github/workflows initial commit 2026-03-28 12:39:41 +00:00
ansible Add ZFS management role: scrub scheduling and pool monitoring 2026-03-29 15:09:54 +00:00
docs initial commit 2026-03-28 12:39:41 +00:00
terraform Remove stale DNS records: chimera, gopher, ecp-dev, and old verification TXT (#14) 2026-03-29 14:08:45 +01:00
.gitignore update readme 2026-03-28 21:06:14 +00:00
.sops.yaml initial commit 2026-03-28 12:39:41 +00:00
Makefile initial commit 2026-03-28 12:39:41 +00:00
README.md update readme 2026-03-28 21:06:14 +00:00

pez-infra

Infrastructure-as-code monorepo for Pez's homelab and cloud fleet. Everything needed to rebuild, configure, and maintain the server infrastructure from scratch.

Architecture Overview

graph TD
    CF[Cloudflare<br/>DNS + CDN] --> HEL[helsinki-a<br/>Caddy proxy<br/><i>Hetzner Cloud</i>]
    HEL --> TS{Tailscale mesh}
    TS --> LB[london-b<br/>Storage, Docker services]
    TS --> LA[london-a<br/>Monitoring<br/>Prometheus, Grafana]
    TS --> CA[copenhagen-a<br/>Gaming<br/>Minecraft, WoW MaNGOS]
    TS --> NUR[nuremberg-a<br/>Mail, poste.io]
    TS --> CC[copenhagen-c<br/>idle]

Hosts

Host Location OS Tailscale IP Role
helsinki-a Hetzner Cloud Linux 100.67.6.27 Reverse proxy (Caddy), main traffic gateway
london-b London Linux 100.84.65.101 Primary storage (ZFS), Docker services
london-a London FreeBSD 100.122.219.41 Monitoring (Prometheus, Grafana)
nuremberg-a Hetzner Cloud Alpine Linux 100.117.235.28 Mail server (poste.io)
copenhagen-a Copenhagen Linux 100.89.206.60 Gaming servers (Minecraft, WoW/MaNGOS)
copenhagen-c Copenhagen Linux 100.115.45.53 Idle/available

Traffic Flow

  1. DNS managed by Cloudflare (Terraform)
  2. Traffic routes to helsinki-a (Caddy reverse proxy)
  3. Caddy forwards to backend services over Tailscale mesh
  4. Auth handled by Authelia with LLDAP backend (on london-b)

Directory Structure

pez-infra/
├── ansible/        # Ansible playbooks, roles, inventory, and all managed files
│   ├── roles/      # Ansible roles (caddy, docker, dotfiles, etc.)
│   ├── services/   # Docker Compose definitions and service configs
│   ├── dotfiles/   # Shell config (fish, nvim, tmux, git, etc.)
│   └── scripts/    # Utility and maintenance scripts
└── terraform/      # Terraform/OpenTofu for Cloudflare, DNS, etc.

Getting Started

Prerequisites

  • SSH access to hosts via Tailscale
  • ansible for configuration management
  • tofu (OpenTofu) or terraform for infrastructure provisioning
  • gh CLI for GitHub operations

Working with this repo

  1. Clone: git clone git@github.com:RWejlgaard/pez-infra.git
  2. Services: Each service has its own directory under ansible/services/ with a docker-compose.yml and config files
  3. Deploy: Ansible playbooks in ansible/ handle deployment (see individual playbook docs)
  4. Infrastructure: Terraform configs in terraform/ manage DNS, tunnels, and access policies

Secrets

Secrets are encrypted in-repo using SOPS + age. Encrypted files use .enc. in their extension (e.g. secrets.enc.yml). See Secrets Management for full setup and usage instructions.

Quick start: ./ansible/scripts/sops-setup.sh

Documentation

Comprehensive documentation lives in docs/:

  • Architecture — Network topology, traffic flow, design principles
  • Networking — Tailscale mesh, DNS flow, physical networking
  • Services — Complete service map with ports, auth, and deployment info
  • Monitoring — Prometheus, Grafana, exporters, status page
  • Getting Started — How to work with this repo

Consolidated Repos

This monorepo replaces several standalone repos:

  • pez-ansibleansible/
  • pez-terraformterraform/
  • pez-grafanaservices/grafana/
  • pez-proxyservices/caddy/
  • pez-docsdocs/ and per-host documentation
  • server-scriptsscripts/ and ansible/