fastly-compute-publish-ignores-draft-versions

Par divinevideo · divine-mobile

Corrige les bugs "le backend existe dans une version draft mais n'est pas accessible depuis le nouveau déploiement Compute" après `fastly compute publish`. À utiliser quand : (1) Vous avez exécuté `fastly service backend create --autoclone` (ou toute modification via le dashboard/CLI créant une version draft) sans activer ce draft, (2) Vous avez ensuite exécuté `fastly compute publish` qui semblait avoir réussi, mais votre modification de backend / ACL / header / dictionary est absente de la version active, (3) Le code Compute retourne des erreurs backend-not-found ou achemine mal les requêtes, (4) Vous constatez avec surprise que votre numéro de version draft a été "ignoré" dans la chaîne de versions. Cause racine : `fastly compute publish` clone depuis la version actuellement active, et non depuis le dernier draft, ce qui fait que les modifications effectuées dans un draft non activé se retrouvent abandonnées.

npx skills add https://github.com/divinevideo/divine-mobile --skill fastly-compute-publish-ignores-draft-versions

fastly compute publish ignore les versions de brouillon non actives

Problème

Les versions de service Fastly sont immuables. Pour modifier un service, vous clonez la version active, éditez le clone (un brouillon), puis activez le clone. Plusieurs outils créent des brouillons :

  • fastly service backend create --autoclone — crée un brouillon à partir de la version active et ajoute le backend
  • fastly service domain create --autoclone — pareil, pour les domaines
  • Bouton « Clone » de l'interface Dashboard
  • fastly compute publish — crée aussi un brouillon, télécharge le WASM, active

Si vous mélangez ces outils sur le même service, vous obtenez une trappe surprenante : chaque outil clone à partir de la version actuellement active, indépendamment, et chacun active son propre clone. Les versions de brouillon qui n'ont jamais été activées sont abandonnées. Leurs modifications sont invisibles pour tout ce que l'outil suivant va cloner.

Exemple de séquence problématique :

t0  Active = v250
t1  $ fastly service backend create --version latest --autoclone \
       --name cloud_run_transcoder --address ...
    → crée v251 (clone de v250) + ajoute le backend
    → v251 est BROUILLON, pas active
    → « latest » dans ce contexte signifie « numéro de version le plus élevé » (v251), pas « version active »

t2  $ fastly compute publish --comment "ship fix"
    → crée v252 (clone de v250, PAS v251) + nouveau WASM
    → prépare et active v253 (clone de v252) + active
    → le changement de backend de v251 n'a jamais été reporté
    → active = v253, qui ne contient PAS cloud_run_transcoder

t3  Le code Compute à v253 appelle send_async("cloud_run_transcoder")
    → le nom du backend n'existe pas sur v253
    → défaillance silencieuse, fire-and-forget la masque

La dénomination est trompeuse : --version latest ne signifie pas « la dernière version active », cela signifie « la version avec le numéro le plus élevé », qui peut être un brouillon que personne n'a activé. Et fastly compute publish ne regarde jamais votre brouillon — il clone à partir de ce qui est actuellement actif. Donc votre changement de backend est orphelin dans une version de brouillon inaccessible, et la version active a le nouveau code mais l'ancienne liste de backends.

Contexte / Conditions déclencheur

  • Les logs Compute affichent Backend X does not exist ou similaire après un déploiement qui « a fonctionné »
  • Les appels send_async(BACKEND) retournent des erreurs que le code avale silencieusement (voir skill fastly-compute-async-request-reliability)
  • fastly service version list --service-id ID affiche un écart ou des timestamps de création désordonnés — par exemple v251 créée à 23:17, v252/v253 créées à 23:27, v253 active, mais v252 a été clonée de v250 et non de v251
  • fastly service backend list --version N où N est active affiche un ensemble de backends DIFFÉRENT de fastly service backend list --version (N-2) où N-2 est le brouillon sur lequel vous pensiez construire
  • Vous avez ajouté une ressource dashboard « juste avant » d'exécuter fastly compute publish et la publication a réussi mais la ressource semble être ignorée

Solution

Détection

# Trouvez toutes les versions et laquelle est active
fastly service version list --service-id YOUR_SERVICE_ID

# Pour chaque version récente, listez les backends (ou la ressource que vous avez ajoutée)
for v in 250 251 252 253 254; do
  echo "=== v$v ==="
  fastly service backend list --service-id YOUR_SERVICE_ID --version $v | grep MY_BACKEND_NAME
done

Si le backend apparaît sur un brouillon non actif (p. ex. v251) mais est absent de la version active (p. ex. v253), vous avez ce bug.

Correction : ajoutez la ressource à la version active actuelle via --autoclone

# Crée un nouveau brouillon cloné à partir de la version active, avec le backend ajouté.
# Activez le brouillon de façon atomique ensuite.
fastly service backend create --service-id YOUR_SERVICE_ID --version latest --autoclone \
  --name cloud_run_transcoder \
  --address divine-transcoder-149672065768.us-central1.run.app \
  --port 443 --use-ssl \
  --ssl-sni-hostname divine-transcoder-149672065768.us-central1.run.app \
  --override-host divine-transcoder-149672065768.us-central1.run.app

# Confirmez que le brouillon a le backend
fastly service backend list --service-id YOUR_SERVICE_ID --version LATEST_DRAFT \
  | grep cloud_run_transcoder

# Activez
fastly service version activate --service-id YOUR_SERVICE_ID --version LATEST_DRAFT

# Purgez le cache pour que les réponses 404/502 empoisonnées disparaissent
fastly purge --all --service-id YOUR_SERVICE_ID

Remarque : --version latest dans la commande backend create ici est sûr car après le précédent fastly compute publish dévié, le parent du dernier brouillon EST la version actuellement active. Vous clonez maintenant à partir de la bonne base.

Prévention (choisissez une option)

  1. Faites tous les changements non-code via fastly compute publish d'abord, puis les changements WASM. Si vous avez exécuté fastly compute publish sans aucun changement dashboard/CLI en attente, la version active est incrémentée de 2 (clone → activate) et il n'y a pas de brouillons abandonnés. Ajoutez votre backend après la publication via --autoclone, qui crée alors un nouveau brouillon à partir de la nouvelle version active, et activez-le.

  2. Activez toujours votre brouillon avant d'exécuter fastly compute publish. Si vous avez exécuté fastly service backend create --autoclone et obtenu v251, activez v251 avant la compute publish. Alors compute publish clonera de v251 et portera le backend.

  3. Traitez chaque version de brouillon comme un changement non livré. Avant tout fastly compute publish, exécutez fastly service version list --service-id ID et vérifiez qu'aucun brouillon n'existe que vous aviez l'intention de livrer. S'il y a des brouillons que vous ne voulez pas, abandonnez-les explicitement ; s'il y a des brouillons que vous voulez, activez-les d'abord.

  4. Utilisez --verbose sur fastly compute publish. La sortie verbose affiche quel numéro de version il a cloné. Si ce numéro est plus ancien que votre dernier brouillon, vous savez que vous avez dévié.

Vérification

Après la correction, confirmez :

# La version active a le backend
fastly service backend list --service-id YOUR_SERVICE_ID --version $(fastly service version list --service-id YOUR_SERVICE_ID | awk '$3=="true"{print $1}') | grep MY_BACKEND_NAME

# Bout en bout : frappez un endpoint Compute qui exerce le backend et vérifiez les logs
# pour un routage réussi (pas d'erreurs « backend does not exist »)
fastly log tail --service-id YOUR_SERVICE_ID | grep -iE "backend|MY_BACKEND"

Pour l'exemple Divine Blossom (2026-04-05), le symptôme était que la correction de PR #59 pour router les déclencheurs du transcodeur via une nouvelle constante TRANSCODER_BACKEND = "cloud_run_transcoder" a été déployée en version 253 mais le backend lui-même était bloqué en v251. Le code Compute était silencieusement 404-ing à chaque send_async vers le transcodeur. La correction a été fastly service backend create --version latest --autoclone → nouvelle v254 avec le WASM et le backend → activate v254 → purge.

Notes

  • Le même problème s'applique à toute ressource que vous pouvez ajouter avec --autoclone : backends, domaines, ACLs, dictionnaires, edge dictionaries, header rules, VCL snippets (sur les services VCL), endpoints de logging. Tout ce qui crée une version de brouillon est à risque.
  • La commande fastly compute publish n'a pas de drapeau --base-version pour dire explicitement « clone à partir de cette version ». Elle clone toujours à partir de la version active.
  • Les services VCL qui mélangent fastly vcl snippet create --autoclone + fastly vcl custom update peuvent tomber dans le même piège.
  • Si plusieurs personnes font des changements concurrence, le risque se multiplie : le brouillon d'une personne peut être invalidé par la publication d'une autre personne sans que l'une ou l'autre ne le remarque.
  • La CLI Fastly n'avertit pas des brouillons abandonnés. Ils n'expirent pas automatiquement (à ma connaissance) ; ils deviennent juste des versions fantôme.
  • Consultez attentivement la sortie de fastly service version list --service-id ID — la colonne « active » vous dit quelle version est en direct ; tout le reste est un brouillon ou une version active précédente. Les timestamps peuvent être trompeurs car les versions de brouillon portent le timestamp de l'appel fastly service version clone, pas du changement de contenu.

Références

  • Comportement de fastly compute publish documenté dans le repo CLI Fastly — voir l'implémentation de la sous-commande publish pour le flux clone-active-and-activate
  • Skill liée : fastly-compute-async-request-reliability — couvre comment le send_async silencieusement défaillant masque ce bug exact quand le backend disparaît
  • Skill liée : fastly-compute-backend-production-setup — couvre le bug cousin « le backend existe localement mais pas en production »

Skills similaires