feat(backup): MinIO S3 backup target on Proxmox host for Velero + CNPG
Stand up a single-node/single-drive MinIO S3 endpoint on the Proxmox host as the off-cluster backup target for Velero (R-STATE-03) and CloudNativePG (R-IDP-05). Ansible (author + executed): - roles/minio_backup_target + playbooks/backup-minio.yml — idempotent, additive only: ZFS dataset Storage/k3s-backups (zstd, quota=100G, /mnt/Storage/k3s-backups, no sharenfs); minio system user; pinned+checksummed MinIO/mc binaries (fetched on the controller since the host has no WAN, copied to host); hardened systemd unit bound to the host's cluster-reachable LAN IP (auto-discovered) on :9000; velero + cnpg buckets; a non-root access key scoped by IAM policy to only those two buckets. - inventory: new [proxmox_hosts] group ([email protected].2.102); overrides the cluster-wide ansible_user. Does not disturb existing k3s node entries. - group_vars/proxmox_hosts/vault.yml (ansible-vault): root + scoped MinIO creds. GitOps hand-off: - platform/backup/minio-credentials.sops.yaml (+ .example) — SOPS/age-encrypted endpoint + scoped key/secret for the Velero/CNPG wiring (WS-STORAGE/WS-SEC). Not yet wired into a kustomization (left for the consuming agents). Verified live: dataset props correct; minio active+enabled bound to 192.168.1.9:9000; S3 endpoint http://192.168.1.9:9000/minio/health/ready returns 200 from an in-cluster pod; buckets velero+cnpg present; scoped key created+policy attached; re-run is idempotent. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
748e9ca55d
commit
ac32f01f7b
13 files changed
+609
No files matched your search
@@ -0,0 +1,29 @@
|
||||
# group_vars for the `proxmox_hosts` group (the Proxmox hypervisor host)
|
||||
|
||||
Target of `playbooks/backup-minio.yml` (role `minio_backup_target`). The role needs the MinIO
|
||||
credentials as **ansible-vault-encrypted** vars here — encrypted, so safe to commit; the passphrase
|
||||
that decrypts them stays out of the repo (`ansible.cfg` → `vault_password_file`).
|
||||
|
||||
## `vault.yml` (committed, encrypted)
|
||||
|
||||
```bash
|
||||
cd infra/ansible
|
||||
ansible-vault create inventory/group_vars/proxmox_hosts/vault.yml
|
||||
# contents:
|
||||
# minio_backup_target_root_user: "…" # MinIO root (host admin only)
|
||||
# minio_backup_target_root_password: "…"
|
||||
# minio_backup_target_access_key: "k3s-backup" # scoped key handed to Velero + CNPG
|
||||
# minio_backup_target_secret_key: "…"
|
||||
```
|
||||
|
||||
The **scoped** access key/secret is mirrored (SOPS-encrypted) for the GitOps side at
|
||||
`platform/backup/minio-credentials.sops.yaml` — the two MUST stay in sync (same key/secret), since
|
||||
the cluster authenticates to this MinIO with them. Rotating means updating BOTH and re-running the
|
||||
playbook (recreates the MinIO user) + reconciling Flux.
|
||||
|
||||
## Notes
|
||||
- This is the **Ansible-bootstrap-layer** secret (host credential), distinct from the platform's
|
||||
in-cluster **SOPS + age** secret (ADR-0007) — different layer, different tool, same values for the
|
||||
scoped key.
|
||||
- `vault.yml` is a vault blob (not parseable YAML) — excluded from the yamllint gate like the other
|
||||
`**/vault.yml`.
|
||||
@@ -0,0 +1,29 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
30633837396565613861623931383238383836356238326436633738613935326461346138373432
|
||||
6234643535303037313337363463633765326239376238380a333331333136396239313733366163
|
||||
33353036366461393530633139636430313736366338313331353163616135303930323038636134
|
||||
6366353362313537330a373863623861663537353539376664306338643539346139396130396632
|
||||
30336231363731616334383863326638636238323565316364303530396636373163393765376438
|
||||
63373263623063656662353434623339316238663535386465653164326236616265616638656639
|
||||
30613466656439396534316339646139343334656165323965323965313361633933633038376663
|
||||
31653539653763623132313533396333643964373032313333613432383433626338376431323731
|
||||
63316163363361303439313266356361613737333066643931656564633038306236363439666435
|
||||
39343536656336343834663464356566373564636531343534343365376332343832343235663339
|
||||
66383561306533323938613738376632626263306337346532643063373166333838333033346365
|
||||
32383136363636643163613334366631653238613166303962656463363663643830343531363533
|
||||
39333630323765643963396562363537396564666462306163336366643739313035636633646661
|
||||
61653637376535393034383631303563363539633265333161363334616239323866353162636632
|
||||
65663830323465393138306361333662383934346438663562316235353035633064643861353334
|
||||
63646435653639316439366139316539653833656561646439323766633139306565383565656261
|
||||
61323230306635343236646438336165643737626132613962633930653461393131303731623438
|
||||
63313265653166643334396461353231343235386434363438623034323762653433303932326630
|
||||
62633464316139353433366338313837646162323231363135353964623035366132643332366662
|
||||
38393465326363616139376465383738626636393639363338653437323832613439313138353033
|
||||
39393765613735666331636230363463306462373238623138316263326339366330333332643833
|
||||
33363764303939326662343665643963333463356638613231363834386132666339393132356538
|
||||
38303362643337366430303165633432666632343536383366653836663135383336316232393936
|
||||
66626632386537333739313432313564633866383132353862626433626366633562346464613066
|
||||
35376332303132326438313132303264313763376163396137356132306131373335346266646532
|
||||
31666230616461386339366461653661323138353662373866316639626134326339643231613337
|
||||
30343361643166353162363866653061313966663435373332353562656164663962326562333038
|
||||
35363834656361393930
|
||||
@@ -37,3 +37,11 @@ localhost ansible_connection=local
|
||||
# with their ansible_host under k3s_secondary; this group only tags the egress role target.
|
||||
[vpn_egress_gateway]
|
||||
k3s-dev-3
|
||||
|
||||
# The Proxmox HYPERVISOR host itself (NOT a k3s node) — target of playbooks/backup-minio.yml,
|
||||
# which stands up the off-cluster MinIO S3 backup target for Velero + CNPG. Reached DIRECTLY
|
||||
# over SSH as root (its own 192.168.2.102:22, the pfSense NAT to the host's 192.168.1.9), so
|
||||
# it overrides the cluster-wide `ansible_user: k3s` from group_vars/all.yml. Distinct from the
|
||||
# `hypervisor` group above (that is `localhost` for host-prereqs.yml, a different machine).
|
||||
[proxmox_hosts]
|
||||
proxmox ansible_host=192.168.2.102 ansible_port=22 ansible_user=root ansible_ssh_private_key_file=~/.ssh/home_network
|
||||
Reference in new issue
Block a user