feat(cnpg): make better (#496)

This commit is contained in:
Antoine Lecompte
2026-08-19 15:27:09 -04:00
committed by GitHub
parent 569c17ff63
commit 045491d437
34 changed files with 586 additions and 18 deletions
+14
View File
@@ -46,6 +46,20 @@ radosgw-admin user create \
--max-buckets=100
```
## Service accounts
| UID | Purpose | Buckets | Caps |
|---|---|---|---|
| `svc-yucca-restic` | michael's restic object store (one bucket per repository) | 100 | — |
| `metrics-worker` | yucca-metrics-worker usage scraping via the RGW admin API | 0 | `buckets=read;usage=read;metadata=read;users=read` |
| `svc-yucca-db-backup` | CNPG (yucca-database) WAL archiving + base backups via the Barman Cloud plugin | 1 | — |
All three are created by `rgw.yml` with predetermined, TF-minted keys (see
[secrets.md](secrets.md)). `svc-yucca-db-backup` never needs a pre-created
bucket: barman creates `yucca-db-backups` on first use, and `--max-buckets=1`
caps the user there. The k8s side consumes the keys plus the RGW cert from the
TF-provisioned `yucca-db-backup-s3` Secret.
## Self-signed certificate handling
The cluster uses a self-signed wildcard certificate. Every client must either
+6 -1
View File
@@ -72,6 +72,8 @@ credentials without waiting for post-bootstrap capture):
|---|---|---|
| `SIETCH_CEPH_S3_SVC_YUCCA_RESTIC_ACCESS_KEY` | `password` | `vault_s3_restic_access_key` -> `ceph_rgw_s3_user_access_key` |
| `SIETCH_CEPH_S3_SVC_YUCCA_RESTIC_SECRET_KEY` | `password` | `vault_s3_restic_secret_key` -> `ceph_rgw_s3_user_secret_key` |
| `SIETCH_CEPH_S3_SVC_YUCCA_DB_BACKUP_ACCESS_KEY` | `password` | `vault_db_backup_access_key` -> `ceph_rgw_db_backup_user_access_key` (also read by the talos stack into the `yucca-db-backup-s3` Secret for CNPG barman) |
| `SIETCH_CEPH_S3_SVC_YUCCA_DB_BACKUP_SECRET_KEY` | `password` | `vault_db_backup_secret_key` -> `ceph_rgw_db_backup_user_secret_key` (same dual consumption) |
**Disaster-recovery items** (populated by `mise run capture` after
deploy -- stored in 1P for recovery if the bootstrap node's filesystem
@@ -84,7 +86,10 @@ is lost):
| `<CLUSTER>_CEPH_CLIENT_ADMIN_KEYRING` | `password` (concealed) | `/etc/ceph/ceph.client.admin.keyring` on bootstrap |
Items are created on the first `mise run capture`; later runs overwrite them
only if the content changed.
only if the content changed. `<CLUSTER>_CEPH_RGW_TLS_CERT` is no longer
DR-only: the talos stack reads it into the `yucca-db-backup-s3` Secret as the
CA bundle CNPG's barman plugin verifies the RGW endpoint with — run the
capture before the talos apply on a fresh cluster.
Item names are derived in `tf/shared/modules/ceph-cluster/main.tf`
(`local.secret_prefix`). Hardcoded `CEPH` (not `role_in_hostname`) so every
@@ -388,6 +388,15 @@ ceph_rgw_metrics_user_access_key: "{{ vault_metrics_worker_access_key }}"
ceph_rgw_metrics_user_secret_key: "{{ vault_metrics_worker_secret_key }}"
ceph_rgw_metrics_user_caps: "buckets=read;usage=read;metadata=read;users=read"
# CNPG database-backup S3 user: the yucca-database cluster's Barman Cloud
# plugin archives WALs/base backups to its own bucket. Keys TF-minted in 1P
# (SPICE_CEPH_S3_SVC_YUCCA_DB_BACKUP_*); rgw.yml (Step 14.6) creates the user
# with max-buckets=1. Mirror of the sietch definition.
ceph_rgw_db_backup_user_uid: svc-yucca-db-backup
ceph_rgw_db_backup_user_display_name: "yucca/db-backup service account (CNPG barman)"
ceph_rgw_db_backup_user_access_key: "{{ vault_db_backup_access_key }}"
ceph_rgw_db_backup_user_secret_key: "{{ vault_db_backup_secret_key }}"
# === Monitoring Stack ===
ceph_prometheus_port: 9095
ceph_grafana_port: 3000
@@ -112,6 +112,15 @@ ceph_rgw_metrics_user_access_key: "{{ vault_metrics_worker_access_key }}"
ceph_rgw_metrics_user_secret_key: "{{ vault_metrics_worker_secret_key }}"
ceph_rgw_metrics_user_caps: "buckets=read;usage=read;metadata=read;users=read"
# CNPG database-backup S3 user: the yucca-database cluster's Barman Cloud
# plugin archives WALs/base backups to its own bucket. Keys TF-minted in 1P
# (SIETCH_CEPH_S3_SVC_YUCCA_DB_BACKUP_{ACCESS,SECRET}_KEY); rgw.yml (Step 14.6)
# creates the user with max-buckets=1.
ceph_rgw_db_backup_user_uid: svc-yucca-db-backup
ceph_rgw_db_backup_user_display_name: "yucca/db-backup service account (CNPG barman)"
ceph_rgw_db_backup_user_access_key: "{{ vault_db_backup_access_key }}"
ceph_rgw_db_backup_user_secret_key: "{{ vault_db_backup_secret_key }}"
# --- RGW DNS + TLS ---
# Virtual-hosted S3 support: setting rgw_dns_name tells RGW to strip this
# suffix from the Host header and treat the remainder as the bucket name.
@@ -899,6 +899,36 @@
changed_when: true
no_log: true
# --- Step 14.6: CNPG database-backup S3 user ---
#
# A dedicated S3 user the yucca-database CNPG cluster (Barman Cloud plugin)
# archives WALs and base backups with. Keys are TF-minted in 1P
# (<CLUSTER>_CEPH_S3_SVC_YUCCA_DB_BACKUP_{ACCESS,SECRET}_KEY) and passed here so
# the consumer is pre-configured with matching credentials. max-buckets=1: barman
# creates its single bucket on first use; this user can never create another.
- name: Check if db-backup RGW user exists
ansible.builtin.command: "radosgw-admin user info --uid={{ ceph_rgw_db_backup_user_uid }}"
register: db_backup_user_check
when: inventory_hostname in groups['ceph_bootstrap']
changed_when: false
failed_when: false
- name: Create db-backup S3 user with predetermined keys for {{ ceph_rgw_db_backup_user_uid }}
ansible.builtin.command: >
radosgw-admin user create
--uid={{ ceph_rgw_db_backup_user_uid }}
--display-name='{{ ceph_rgw_db_backup_user_display_name }}'
--access-key='{{ ceph_rgw_db_backup_user_access_key }}'
--secret-key='{{ ceph_rgw_db_backup_user_secret_key }}'
--max-buckets=1
register: db_backup_user_create
when:
- inventory_hostname in groups['ceph_bootstrap']
- db_backup_user_check.rc != 0
changed_when: true
no_log: true
- name: Ensure metrics-worker RGW user has read-only admin caps
ansible.builtin.shell: |
set -o pipefail