Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
164 lines
6.5 KiB
Markdown
164 lines
6.5 KiB
Markdown
# 01 — Prérequis
|
|
|
|
**Durée : 2 à 3 h.** Rien de technique ici, mais tout bloque si un élément
|
|
manque au moment où vous en avez besoin.
|
|
|
|
---
|
|
|
|
## 1. Comptes à créer ou vérifier
|
|
|
|
| Service | Rôle | À faire | Coût |
|
|
|---|---|---|---|
|
|
| **Hetzner Cloud** | Serveurs, réseau, firewalls, volume | Créer un **projet dédié** `xpeditis-prod`, séparé de la preprod. Activer la **2FA**. | ~50 €/mois |
|
|
| **Hetzner Storage Box** | Seconde copie des dumps | Commander une **BX11** (1 To). Commande séparée de Hetzner Cloud. | 3,90 €/mois |
|
|
| **Hetzner Object Storage** | Documents + archives WAL-G | Activer dans le projet, région `fsn1`. | ~6 €/mois |
|
|
| **Cloudflare** | DNS, WAF, anti-DDoS | Zone `xpeditis.com` déléguée. Plan Free suffisant. **2FA obligatoire.** | 0 € |
|
|
| **Registrar du domaine** | `xpeditis.com` | Pointer les serveurs de noms vers Cloudflare. Activer le **verrou de transfert**. | ~10 €/an |
|
|
| **Scaleway Container Registry** | Images Docker | Déjà utilisé par la preprod. Vérifier que `REGISTRY_TOKEN` est encore valide. | ~1 €/mois |
|
|
| **Brevo** | E-mails transactionnels | Créer une **nouvelle clé SMTP de production** (celle de preprod est compromise). Vérifier le domaine expéditeur. | 0 → 19 €/mois |
|
|
| **Stripe** | Paiements | Passer le compte en **mode Live**. Récupérer `sk_live_…`, créer le webhook de production, noter les 6 identifiants de tarif. | % du volume |
|
|
| **Sentry** | Erreurs applicatives | Projet `xpeditis-prod` distinct de la preprod. | 0 → 26 €/mois |
|
|
| **Pappers** | Vérification SIRET | Clé API. Facultatif : sans clé, la vérification est simplement ignorée. | ~3 €/mois |
|
|
| **Discord** | Alertes et déploiements | Deux webhooks : `#deploiements` et `#alertes`. | 0 € |
|
|
| **healthchecks.io** ou **BetterStack** | Surveillance externe | Un *heartbeat* pour les sauvegardes, un contrôle d'uptime sur `https://app.xpeditis.com`. | 0 € |
|
|
|
|
> **Pourquoi un projet Hetzner séparé** — le token API est valable pour tout un
|
|
> projet. Un token de preprod compromis ne doit pas pouvoir détruire la
|
|
> production. La séparation est aussi ce qui isole les deux réseaux privés.
|
|
|
|
---
|
|
|
|
## 2. Décisions à trancher maintenant
|
|
|
|
### 2.1 Adresse e-mail d'exploitation
|
|
|
|
Une adresse **relevée** est nécessaire pour :
|
|
- Let's Encrypt (avertissements d'expiration si le renouvellement casse) ;
|
|
- Hetzner (incidents, maintenances) ;
|
|
- Cloudflare et le registrar.
|
|
|
|
Recommandé : `ops@xpeditis.com`, redirigée vers votre boîte personnelle.
|
|
Remplacez `ops@xpeditis.com` dans `infra/prod/k8s/cluster/cluster-issuer.yaml`
|
|
si vous choisissez autre chose.
|
|
|
|
### 2.2 IP d'administration
|
|
|
|
Terraform refuse `0.0.0.0/0` pour SSH. Il vous faut une IP publique stable.
|
|
|
|
```bash
|
|
curl -s https://ifconfig.me
|
|
```
|
|
|
|
- **IP fixe** (fibre pro, bureau) → parfait.
|
|
- **IP dynamique** → deux options :
|
|
- relancer `terraform apply` quand elle change (acceptable si c'est rare) ;
|
|
- passer par un VPN à IP fixe (Mullvad, un petit serveur Hetzner CX22 à 4 €).
|
|
|
|
### 2.3 Noms de domaine
|
|
|
|
La configuration livrée suppose :
|
|
|
|
| Domaine | Sert |
|
|
|---|---|
|
|
| `xpeditis.com`, `www.xpeditis.com` | vitrine (pages publiques du frontend) |
|
|
| `app.xpeditis.com` | application (origine des cookies d'authentification) |
|
|
| `api.xpeditis.com` | API |
|
|
| `grafana.xpeditis.com` | supervision |
|
|
|
|
Pour un autre découpage, modifiez `k8s/base/02-configmap-backend.yaml`
|
|
(`APP_URL`, `CORS_ORIGIN`, `COOKIE_DOMAIN`) **et** `k8s/base/09-ingress.yaml`.
|
|
|
|
> `COOKIE_DOMAIN=.xpeditis.com` (avec le point initial) est **indispensable** :
|
|
> l'API pose le cookie sur `api.xpeditis.com`, le middleware Next.js le lit sur
|
|
> `app.xpeditis.com`. Sans le point, la connexion réussit mais l'utilisateur est
|
|
> renvoyé sur `/login` — le symptôme est déroutant, la cause est ici.
|
|
|
|
---
|
|
|
|
## 3. Outils sur votre poste
|
|
|
|
```bash
|
|
# macOS
|
|
brew install terraform kubectl sops age hcloud jq rsync
|
|
brew install --cask docker # pour construire des images localement
|
|
|
|
# Vérification
|
|
terraform version # >= 1.6
|
|
kubectl version --client
|
|
sops --version # >= 3.8
|
|
age --version
|
|
hcloud version
|
|
jq --version
|
|
```
|
|
|
|
`shellcheck` est facultatif mais utilisé par `make validate` :
|
|
```bash
|
|
brew install shellcheck
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Clés SSH
|
|
|
|
Trois clés distinctes, jamais interchangeables :
|
|
|
|
```bash
|
|
# 1. Administration (vous, sur les deux serveurs)
|
|
ssh-keygen -t ed25519 -a 100 -C "xpeditis-prod-admin" -f ~/.ssh/xpeditis_prod
|
|
|
|
# 2. Déploiement CI (GitHub Actions → app-01, restreinte à un script)
|
|
ssh-keygen -t ed25519 -a 100 -C "github-actions-prod" -f ~/.ssh/xpeditis_ci
|
|
|
|
# 3. Storage Box (db-01 → Storage Box, pour les dumps)
|
|
ssh-keygen -t ed25519 -a 100 -C "xpeditis-storagebox" -f ~/.ssh/xpeditis_storagebox
|
|
```
|
|
|
|
Protégez la clé d'administration par une phrase de passe. Celles de la CI et de
|
|
la Storage Box sont utilisées par des automates : elles ne peuvent pas en avoir,
|
|
c'est justement pourquoi leurs privilèges sont limités.
|
|
|
|
**Sauvegardez les trois clés privées dans votre gestionnaire de mots de passe.**
|
|
Perdre la clé d'administration signifie repasser par la console Hetzner en mode
|
|
secours.
|
|
|
|
---
|
|
|
|
## 5. Clé de chiffrement des secrets
|
|
|
|
C'est **la** clé à ne pas perdre : elle déchiffre tous les secrets de
|
|
production. Sa création est détaillée dans [06-secrets-sops.md](./06-secrets-sops.md),
|
|
mais générez-la maintenant, vous en aurez besoin partout :
|
|
|
|
```bash
|
|
mkdir -p ~/.config/sops/age
|
|
age-keygen -o ~/.config/sops/age/keys.txt
|
|
chmod 600 ~/.config/sops/age/keys.txt
|
|
grep 'public key' ~/.config/sops/age/keys.txt
|
|
```
|
|
|
|
Générez **aussi une clé de secours**, stockée hors ligne (papier dans un coffre,
|
|
ou clé USB chiffrée rangée ailleurs). Les deux clés publiques iront dans
|
|
`infra/prod/.sops.yaml`. Sans clé de secours, la perte de votre poste = la perte
|
|
définitive de tous les secrets de production.
|
|
|
|
---
|
|
|
|
## 6. Contrôle avant de passer à la suite
|
|
|
|
```
|
|
[ ] Projet Hetzner Cloud `xpeditis-prod` créé, 2FA activée
|
|
[ ] Storage Box BX11 commandée (l'activation prend jusqu'à 1 h)
|
|
[ ] Zone Cloudflare active pour xpeditis.com, 2FA activée
|
|
[ ] Compte Stripe en mode Live, webhook de production créé
|
|
[ ] Nouvelle clé SMTP Brevo de production créée
|
|
[ ] Domaine expéditeur vérifié chez Brevo (SPF/DKIM prêts à publier)
|
|
[ ] ops@xpeditis.com relevée
|
|
[ ] IP d'administration connue et stable
|
|
[ ] Outils installés (terraform, kubectl, sops, age, hcloud, jq)
|
|
[ ] 3 clés SSH générées et sauvegardées
|
|
[ ] Clé age principale + clé de secours générées
|
|
[ ] Webhooks Discord créés
|
|
```
|
|
|
|
→ **Suite : [02 — Provisioning Hetzner](./02-provisioning-hetzner.md)**
|