Septembre 2026

Le provider Terraform Pathly, en pratique

APICoulisses

Il est publié sur le registre. Voici les fichiers qu’on écrit vraiment : le plus petit qui serve à quelque chose, un parc entier décrit comme une donnée, et la reprise d’une surveillance créée à la main.

Installer

Le provider s’appelle pathlyhq/pathly sur le registre public. Il n’y a rien à compiler ni à déposer dans un miroir : la déclaration de version suffit, et la commande d’initialisation le télécharge. La contrainte ~> 0.1 accepte les correctifs et refuse une éventuelle 0.2, ce qui est le bon réglage tant que le schéma n’est pas figé par un 1.0.

terraform {
  required_version = ">= 1.6"
  required_providers {
    pathly = {
      source  = "pathlyhq/pathly"
      version = "~> 0.1"
    }
  }
}

# Aucun argument : la clé vient de PATHLY_API_TOKEN.
provider "pathly" {}

Le bloc provider est vide, et ce n’est pas une négligence. La clé se lit dans la variable d’environnement PATHLY_API_TOKEN. Passée par une variable Terraform, elle finirait en clair dans le fichier d’état, que l’on oublie toujours de chiffrer avant de l’avoir déjà poussé quelque part. Le provider refuse par ailleurs de parler en http à autre chose que localhost : la clé voyage dans un en-tête d’autorisation, elle serait lisible par tous les intermédiaires.

Le plus petit fichier qui serve à quelque chose

Un scénario, une adresse, un intervalle, et un texte qu’on s’attend à trouver dans la page. Ce dernier point fait la différence entre surveiller un serveur et surveiller un site : une page d’erreur applicative répond très bien en HTTP 200, et seul le texte attendu la démasque.

resource "pathly_scenario" "site" {
  name         = "Home page"
  url          = "https://shop.example.com"
  interval_sec = 300
  expect_text  = "Our products"
  tags         = ["prod"]
}

Un parc décrit comme une donnée

Au-delà de trois ou quatre parcours, un bloc par ressource devient une liste qu’on relit à chaque ajout. Les décrire dans une variable et boucler dessus change la nature du fichier : ajouter un parcours devient une ligne de données, et les règles de seuil, de dossier et d’étiquette restent les mêmes pour tous sans qu’on ait à y penser.

resource "pathly_scenario" "journey" {
  for_each = var.journeys

  name         = each.value.name
  url          = each.value.url
  interval_sec = each.value.interval_sec
  expect_text  = each.value.expect_text

  # Un seuil de latence par parcours : le paiement tolère
  # moins qu'une page d'accueil servie depuis le cache.
  max_latency_ms  = each.value.max_latency_ms
  expected_status = 200
  severity        = each.value.severity
  tags            = concat(["terraform", var.environment], each.value.tags)
}

# Un objectif de disponibilité par parcours critique, qui
# alerte à 80 % du budget d'erreur dépensé : au-delà, il
# reste trop peu de marge pour le reste du mois.
resource "pathly_sla_target" "objective" {
  for_each = {
    for key, j in var.journeys : key => j if j.severity == "critical"
  }

  scenario_id          = pathly_scenario.journey[each.key].id
  objective_pct        = 99.9
  window_days          = 30
  exclude_maintenance  = true
  warn_at_budget_ratio = 0.8
}

L’objectif de disponibilité exclut les fenêtres de maintenance, ce qui n’a de sens que si ces fenêtres existent aussi dans le code. Une maintenance déclarée d’un côté et un objectif qui l’ignore de l’autre produisent un budget d’erreur dépensé par une coupure annoncée, c’est-à-dire une alerte qui punit une opération planifiée.

# Sauvegarde hebdomadaire : les échecs dans cette fenêtre
# ne dépensent pas le budget d'erreur.
resource "pathly_maintenance_window" "backup" {
  weekday      = 7 # dimanche
  start_minute = 3 * 60
  duration_min = 120
  reason       = "Weekly backup"
}

Repérer ce qui a été créé à la main

C’est l’usage le plus utile de la source de données, et celui auquel on pense le moins. Elle relit l’inventaire tel que l’API le voit. Comparé à ce que le code déclare, l’écart nomme les scénarios créés dans la console et absents des fichiers : ceux que personne ne révise, et que personne ne supprimera lors du démantèlement d’un environnement.

data "pathly_scenarios" "prod" {
  filter_tag = var.environment
  depends_on = [pathly_scenario.journey]
}

output "scenarios_outside_terraform" {
  value = [
    for s in data.pathly_scenarios.prod.scenarios : s.name
    if !contains([for j in pathly_scenario.journey : j.id], s.id)
  ]
}

Le même raisonnement vaut pour les valeurs que l’API ne rend jamais. La destination d’un webhook s’écrit et ne se relit pas : à la place, une empreinte de douze caractères, qui change dès que l’adresse change. Elle ne permet pas de reconstituer la destination, et suffit à voir en plan qu’elle a été modifiée ailleurs.

output "webhook_fingerprint" {
  value = pathly_webhook.alerts.url_fingerprint
}

Reprendre une surveillance existante

Personne ne recrée son parc pour passer au code, et le provider ne le demande pas. Chaque ressource s’importe par son identifiant, celui que porte l’adresse du scénario dans la console. Après l’import, le plan montre l’écart entre l’existant et ce que le fichier décrit : tant qu’il n’est pas vide, l’application modifiera le scénario en place plutôt que d’en créer un second.

terraform import pathly_scenario.checkout mon_01H8ZK…

Le critère qui décide si tout cela est utilisable tient en une phrase : après une application, le plan suivant doit être vide. Un provider qui propose une modification à chaque passage apprend très vite à ses utilisateurs à ne plus lire ses plans, et le jour où le plan dit quelque chose de vrai, personne ne le voit. C’est le travail le moins visible du provider, et c’est celui sur lequel ses tests insistent le plus.

Ce que le provider ne fera jamais

Ces absences ne sont pas des fonctionnalités en retard. Un provider qui couvre tout finit par exiger une clé qui peut tout, et cette clé traîne ensuite dans les variables d’un pipeline que lisent plus de gens qu’on ne croit. Ce qui manque ici manque exprès, et se fait dans l’interface, par un humain identifié.

Voyez ce que ça donne sur votre site

Audit gratuit en 30 secondes — ou enregistrez un parcours et surveillez-le chaque jour.