dynv6 sert mal un TXT _acme-challenge à la racine de la zone : l'API ne
le liste ni ne le supprime, et un seul de ses trois serveurs le renvoie.
Le défi DNS-01 de la prod échouait donc à chaque essai, alors que rec. et
dev. passaient. La prod rejoint ses voisines en sous-domaine, ce qui aligne
aussi les trois noms sur les environnements.
- provision-host.sh : hôte prod.$DOMAINE, enregistrement A prod publié.
- Makefile : --dnssleep 90, le temps que les trois serveurs de dynv6
servent le TXT avant la validation multi-réseaux de Let's Encrypt.
- deploy.yml, ADR 0018, 10-infra.md, infra/README.md, Terraform.
deSEC n'ouvre plus de nouveaux domaines dedyn.io, et duckdns.org est
filtré par l'école. dynv6 répond depuis les postes et depuis la VM.
- Zone enervision-g3.dynv6.net ; provision-host.sh pointe la zone, rec
et dev vers la VM par l'API dynv6 (bloc Python, idempotent).
- make tls-dns01 remplace tls-desec : DNS01_API et DNS01_JETON_VAR
nomment le greffon acme.sh, le jeton vit dans ../dns.token quel que
soit le fournisseur. Un domaine acheté ne demandera que ces variables.
- deploy.yml ne demande un certificat qu'à un .env qui ne porte plus de
nom en .local.
- ADR 0018 renommé noms-publics : deSEC et DuckDNS en alternatives.
Le filtrage du réseau de l'école bloque duckdns.org, site et API, depuis
les postes comme depuis la VM : sans API, pas de défi DNS-01. deSEC
(dedyn.io) répond depuis les deux.
- Domaine enervision-g3.dedyn.io ; provision-host.sh publie par l'API
deSEC l'enregistrement du domaine et son joker vers la VM.
- make tls-desec remplace tls-duckdns. acme.sh recopie le jeton dans
acme/account.conf : le dossier est retiré aux autres comptes.
- deploy.yml ne demande un certificat qu'à un .env déjà réaligné sur
le domaine deSEC, pour ne pas faire échouer un déploiement en cours
de migration.
Les trois environnements passent sur enervision-g3.duckdns.org, rec. et
dev. : noms publics qui visent l'IP privée de la VM, donc résolus sans
/etc/hosts sur le réseau de l'école et injoignables ailleurs (ADR 0018).
- infra/front : nginx sur le réseau de l'hôte, seul exposé en 80 et 443.
Aiguille par SNI vers la stack visée sans déchiffrer le TLS, et lui
transmet l'IP du client en PROXY protocol.
- Proxy de stack : écouteur 4443 en PROXY protocol, real_ip_header ;
sans lui, limit_req et get_client_ip() compteraient tous les postes
comme un seul. PROXY_FRONT_PORT le publie sur 127.0.0.1.
- make tls-duckdns : Let's Encrypt par défi DNS-01 via l'API DuckDNS
(acme.sh 3.1.6), rejouable, rejoué à chaque déploiement et chaque nuit.
- provision-host.sh fait foi pour l'adressage et les secrets : un .env
existant garde ses secrets, reçoit ceux qui manquent (supervision) et
voit hôte et ports réalignés. Planifie le renouvellement des certificats.
- deploy.yml : nouvelles URL, sonde prod sur 10443, front-up en prod.
- Terraform : variable domaine. CI : validation du frontal.
Troisième projet Compose sur la VM ENI, /srv/enervision/dev, alimenté par
workflow_dispatch de n'importe quelle branche autre que dev et main
(https://dev.enervision.local:9443). La recette suit toujours dev, la
production main.
- deploy.yml : routage main -> prod, dev -> rec, autre -> dev ; groupe de
concurrence par environnement et non plus par branche.
- provision-host.sh : prépare le dossier dev (ports 9443, 5435, 8027, 8084) ;
passe safe.directory à git, faute de quoi un second passage en root, celui
de terraform apply, échoue sur les clones déjà remis au runner.
- ADR 0017, 10-infra.md, 50-cicd.md, infra/README.md à jour.
--name reprenait runner_labels : un runner et son label portaient le meme
eni-g3. Deux machines qui reprendraient cette racine s'enregistreraient sous
le meme nom, ce que GitHub refuse. Le nom vaut desormais celui de l'hote,
resolu sur la machine, et runner_nom permet de le forcer.
Point 2 de la revue de la PR #144.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Le seul Terraform du dépôt installait un cluster k3s que rien ne consomme, et
sa racine ne passait même pas `terraform init` : depuis Terraform 1.x, un
provisioner `destroy` impose que tout le bloc `connection` ne lise que `self`,
et celui du module k3s lisait `var.*`. Il est corrigé en batissant la connexion
sur `triggers`, où ne figurent que l'adresse, le port, l'utilisateur et le
chemin de la clé : jamais la clé ni un mot de passe.
`environments/vm-eni` provisionne la machine qui porte la recette et la
production : Docker et le plugin Compose, `scripts/provision-host.sh`, puis
l'enregistrement du runner. Rien n'y construit d'image ni ne lance de
conteneur, et un `apply` n'interrompt pas la stack qui tourne. Le déploiement
continu ne bouge pas : `deploy.yml` reste le seul chemin de livraison.
`environments/dev` devient `k3s-cible`, parce qu'il provisionnait un cluster et
pas un environnement applicatif, et que `rec` et `prod` vivent sur la même
machine. `environments/prod`, dossier vide, disparaît.
`infra.yml` formate et valide chaque racine à chaque push : c'est l'absence
d'un tel job qui a laissé ce Terraform cassé sans que rien ne le dise. La
boucle parcourt `environments/*`, une racine ajoutée est couverte sans y
toucher.
ADR 0010 pour la frontière entre provisionnement et livraison, et la doc
d'architecture alignée dessus.