Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
name: Harden production
name: Configure production cluster
run-name: Configure the production cluster for ${{ github.actor }}

"on":
workflow_dispatch:
inputs:
confirmation:
description: Type APPLY_PRODUCTION_HARDENING
description: Type CONFIGURE_PRODUCTION
required: true
type: string
prove_scaling:
Expand All @@ -27,8 +28,8 @@ concurrency:
cancel-in-progress: false

jobs:
metrics-server:
name: Install and prove Metrics API
configure:
name: Configure production safeguards
runs-on: ubuntu-latest
environment: production
timeout-minutes: 20
Expand All @@ -39,11 +40,11 @@ jobs:
run: |
set -euo pipefail
[ "$GITHUB_REF" = refs/heads/main ] || {
echo "Production hardening must run from main" >&2
echo "Production configuration must run from main" >&2
exit 1
}
[ "$CONFIRMATION" = APPLY_PRODUCTION_HARDENING ] || {
echo "confirmation must equal APPLY_PRODUCTION_HARDENING" >&2
[ "$CONFIRMATION" = CONFIGURE_PRODUCTION ] || {
echo "confirmation must equal CONFIGURE_PRODUCTION" >&2
exit 1
}

Expand Down Expand Up @@ -92,7 +93,7 @@ jobs:
API_ORIGIN: ${{ vars.API_ORIGIN }}
run: ./scripts/apply-network-policies.sh

- name: Verify public application after hardening
- name: Verify the application after configuration
env:
API_ORIGIN: ${{ vars.API_ORIGIN }}
run: |
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: Deploy production
name: Deploy to production
run-name: Deploy ${{ inputs.version || 'a pinned image' }} to production

"on":
workflow_dispatch:
Expand All @@ -26,7 +27,7 @@ concurrency:

jobs:
deploy:
name: Roll out immutable images
name: Deploy the selected server image
runs-on: ubuntu-latest
environment: production
timeout-minutes: 180
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
# Ops CI — formate et valide l'IaC (prettier + terraform fmt).
name: Ops CI
# Validates the infrastructure definitions on every proposed change.
name: Validate infrastructure
run-name: Infrastructure checks for ${{ github.ref_name }}

"on":
push:
Expand All @@ -12,12 +13,12 @@ permissions:
contents: read

concurrency:
group: ops-ci-${{ github.ref }}
group: infrastructure-validation-${{ github.ref }}
cancel-in-progress: true

jobs:
validate:
name: Format & validate
name: Validate infrastructure definitions
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ K8S_MANIFESTS := $(shell find k8s -name '*.yaml' ! -name '*.sops.yaml' | sort)
validate-templates secret-dry-run secret-apply secrets-dry-run secrets-apply \
backup-secret-configure backup-enable backup-run backup-verify backup-status \
cert-manager-install tls tls-staging tls-status \
metrics hpa pdb load harden soft-affinity hard-affinity \
metrics hpa pdb load harden \
minikube minikube-host-preflight minikube-up minikube-deploy minikube-hosts minikube-smoke minikube-down

help: ## Affiche cette aide
Expand Down Expand Up @@ -443,12 +443,6 @@ hpa: metrics ## Applique le HPA du server (sauté tant que le Deployment n'exist
load: ## Génère de la charge HTTP (test autoscaling) contre l'hôte web
WEB_URL=http://$(WEB_HOST):30021 ./scripts/load.sh

soft-affinity: ## Relâche l'anti-affinity required->preferred (clusters nodes < replicas)
./scripts/soft-affinity.sh on

hard-affinity: ## Restaure l'anti-affinity stricte (preferred->required)
./scripts/soft-affinity.sh off

harden: pdb hpa ## Applique PDB + HPA (ce qui est prêt)

## --- Cluster local (minikube, sans DigitalOcean) ---------------------------
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="https://raw.githubusercontent.com/wiki/opswarden-git/opswarden/assets/opswarden-ops/heroicon.png" alt="OpsWarden" width="120" />
<h1>OpsWarden - Infrastructure</h1>
<p>
<img src="https://github.com/opswarden-git/opswarden-ops/actions/workflows/ops-ci.yml/badge.svg" alt="CI" />
<img src="https://github.com/opswarden-git/opswarden-ops/actions/workflows/validate.yml/badge.svg?label=CI" alt="CI" />
<img src="https://img.shields.io/badge/License-Apache_2.0-blue?style=flat" alt="License: Apache 2.0" />
<img src="https://img.shields.io/badge/Kubernetes-326ce5?style=flat&logo=kubernetes&logoColor=white" alt="Kubernetes" />
<img src="https://img.shields.io/badge/DigitalOcean-%230167ff?style=flat&logo=digitalOcean&logoColor=white" alt="DigitalOcean" />
Expand Down
176 changes: 0 additions & 176 deletions docs/deployment-audit.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/recovery/current-contract.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/recovery/legacy-contract.md

This file was deleted.

4 changes: 2 additions & 2 deletions docs/runbooks/postgres-credential-rotation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PostgreSQL credential rotation (step 2C)
# Rotate PostgreSQL credentials

OpsWarden uses four distinct PostgreSQL identities:
OpsWarden uses five distinct PostgreSQL identities:

- `opswarden_admin`: bootstrap only, stored in `postgres-secret`;
- `opswarden_owner`: `NOLOGIN` owner of the database and schema;
Expand Down
33 changes: 5 additions & 28 deletions docs/runbooks/spaces-backups.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,41 +84,18 @@ Un upload réussi ne suffit pas: le chantier n'est terminé qu'après le contrô
du checksum et la restauration réussie du dernier dump dans le PostgreSQL
isolé du Job de vérification.

## Preuve de production du 30 juillet 2026

Le contexte `do-fra1-opswarden-cluster`, namespace `default`, a produit les
preuves suivantes:

- `postgres-backup-manual-20260730191627`: dump réussi, trois fichiers chiffrés
envoyés dans Spaces puis retéléchargés par `rclone check`, zéro différence;
- `postgres-backup-verify-fv75q`: téléchargement du dernier backup, checksum
SHA-256 et gzip valides, restauration complète dans PostgreSQL 18 isolé,
relation `public.users` présente et migrations SQLx réussies;
- CronJob `postgres-backup`: planification quotidienne à `02:17 UTC`, préfixe
`production/postgres` et rétention `30d`.

Dans DOKS FRA1, le nom régional Spaces se résout actuellement vers
`10.114.15.254`. Les NetworkPolicies d'upload et de vérification autorisent
uniquement cette adresse en `/32` sur TCP 443, tout en continuant à refuser les
autres destinations RFC1918. Si DigitalOcean change cette résolution, validez
la nouvelle adresse avant de modifier l'allowlist.

## Supervision et preuves différées
## Supervision

kube-state-metrics est limité aux `Jobs` et `CronJobs` du namespace `default`.
Prometheus alerte si le CronJob est absent ou suspendu, si un Job planifié
échoue, si aucune exécution planifiée n'a jamais réussi après 26 heures, ou si
le dernier succès dépasse 26 heures.

Les preuves suivantes sont nécessairement différées:

- première exécution réellement créée par le contrôleur CronJob à `02:17 UTC`;
- suppression d'objets âgés de plus de `30d`.

Ne marquez ces deux preuves terminées qu'après observation de l'état réel. La
vérification complète par téléchargement reste quotidienne pour privilégier
La vérification complète par téléchargement reste quotidienne pour privilégier
l'intégrité tant que la base est petite. Réévaluez ce choix si les frais de
récupération Cold Storage ou la taille du dump deviennent significatifs.
récupération ou la taille du dump deviennent significatifs. Vérifiez aussi
périodiquement qu'une exécution est réellement créée à `02:17 UTC` et que les
objets âgés de plus de `30d` sont supprimés.

Conservez une copie chiffrée ou matérielle de
`~/.config/sops/age/keys.txt` dans un emplacement de récupération distinct. Ne
Expand Down
4 changes: 2 additions & 2 deletions k8s/server/server.hpa.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# HorizontalPodAutoscaler du serveur OpsWarden (basé CPU).
# Requiert metrics-server (DOKS le fournit ; en local `make metrics`).
# Scaler au-delà des replicas de base suppose une anti-affinity *preferred*
# (pas required) sur le Deployment server (cf. scripts/soft-affinity.sh).
# Scaler au-delà des replicas de base suppose l'anti-affinity souple définie
# sur le Deployment server.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
Expand Down
Loading