ServicesÀ proposNotesContact Me contacter →
EN FR
Note

GitHub Actions pour le scheduling dbt

Utiliser les workflows schedulés GitHub Actions comme exécuteur dbt sans infrastructure — ce qu'il couvre bien, ses limites, et quand le préférer à Cloud Run.

Planté
dbtgcpdata engineeringautomationcost optimization

Les workflows schedulés GitHub Actions peuvent exécuter dbt build selon une expression cron, avec des credentials stockées en tant que secrets du dépôt et Python installé à chaque exécution. Pour les projets dbt déjà sur GitHub, cette approche ne nécessite aucune infrastructure supplémentaire, aucune configuration GCP et aucune nouvelle plateforme.

La configuration

Une exécution dbt schedulée minimale sur GitHub Actions :

name: dbt daily run
on:
schedule:
- cron: '0 6 * * *'
workflow_dispatch:
jobs:
dbt-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install dbt-bigquery
- run: dbt deps && dbt build --target prod
env:
DBT_PROFILES_DIR: .
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}

Le déclencheur workflow_dispatch permet de lancer manuellement une exécution depuis l’interface GitHub Actions, utile pour le débogage et pour les exécutions déclenchées en dehors du planning. Ajoutez-le à chaque workflow schedulé.

Pour l’authentification BigQuery, deux options s’offrent à vous : stocker le JSON du compte de service en tant que secret et le passer via GOOGLE_APPLICATION_CREDENTIALS, ou utiliser l’intégration OIDC de GitHub avec GCP Workload Identity Federation pour une authentification sans clé. L’approche sans clé est plus sécurisée — pas de credentials à longue durée de vie dans vos secrets — mais nécessite une configuration GCP unique pour établir la relation de confiance.

Pour profiles.yml, vous pouvez soit committer un profil de production dans le dépôt (sans valeurs sensibles) et passer le compte de service séparément, soit générer le profil dynamiquement dans l’étape du workflow en utilisant des variables d’environnement. Cette dernière approche garde tous les secrets hors du dépôt :

- name: Create profiles.yml
run: |
mkdir -p ~/.dbt
cat > ~/.dbt/profiles.yml << EOF
my_project:
target: prod
outputs:
prod:
type: bigquery
method: service-account
project: ${{ secrets.GCP_PROJECT_ID }}
dataset: analytics
keyfile: /tmp/gcp-key.json
threads: 4
EOF
echo '${{ secrets.GCP_SA_KEY }}' > /tmp/gcp-key.json

Ce que vous obtenez

Zéro infrastructure supplémentaire. Le YAML du workflow est versionné aux côtés du projet dbt, revu en PR, et visible pour chaque membre de l’équipe ayant accès au dépôt.

Niveau gratuit de calcul. Les dépôts privés obtiennent 2 000 minutes par mois dans le niveau gratuit. Une exécution dbt typique prend 3 à 10 minutes y compris l’installation de Python et des dépendances, ce qui couvre les planifications quotidiennes et souvent horaires dans le niveau gratuit. Les dépôts publics ont des minutes illimitées.

Support du déclenchement manuel. L’événement workflow_dispatch permet des exécutions à la demande depuis l’interface GitHub sans modifier le planning cron.

Visibilité basée sur les PR. Les modifications du fichier workflow passent par le processus PR normal, avec une piste d’audit complète et git revert comme mécanisme de rollback.

Les compromis

GitHub Actions pour le scheduling présente des limites réelles qu’il vaut la peine d’intérioriser avant de s’y engager.

Le timing est approximatif. GitHub ne garantit pas l’exécution cron exacte pendant les périodes de forte charge. Un workflow schedulé à 6h du matin peut démarrer à 6h03 ou 6h15. Pour les rafraîchissements analytiques où une fenêtre de 15 minutes est acceptable, c’est bien. Si un système en aval dépend de dbt se terminant avant 6h05, GitHub Actions ne le garantira pas de manière fiable.

Démarrage à froid à chaque exécution. Chaque exécution installe Python, dbt-bigquery et tous vos packages dbt depuis zéro. Sur un projet avec de nombreux packages, cela peut ajouter 3 à 5 minutes à chaque exécution. Il n’y a pas d’équivalent de mise en cache de packages comparable à ce qu’offre un conteneur dédié. Vous pouvez atténuer cela avec le cache Actions pour les packages pip, mais c’est une étape de configuration supplémentaire :

- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}

Pas de logique de retry. Un build dbt échoué ne se relance pas automatiquement. Vous pouvez ajouter de la logique de retry manuellement avec une action tierce ou des boucles shell, mais ce n’est pas natif. Pour les pipelines où les échecs transitoires (timeouts réseau, pics de quota BigQuery) sont fréquents, l’absence de retry automatique est une lacune matérielle comparée à la gestion native des retries de Cloud Run Jobs.

Pas de conscience des dépendances entre workflows. Les workflows GitHub Actions ne se connaissent pas mutuellement. Si vous avez un workflow d’ingestion qui doit se terminer avant votre workflow dbt, vous ne pouvez pas exprimer nativement « attendre la fin du workflow A avant de démarrer le workflow B ». Des solutions de contournement existent (interrogation de l’API, utilisation des sorties de workflow) mais elles sont fragiles. C’est la limitation structurelle la plus significative — dès que vous avez besoin que « dbt s’exécute seulement après la réussite de la synchronisation Fivetran », GitHub Actions cesse d’être le bon outil.

Les artefacts sont transitoires. dbt génère des artefacts d’exécution (manifest.json, run_results.json) sur lesquels les outils en aval et les comparaisons basées sur l’état s’appuient. Dans GitHub Actions, ces artefacts ne sont pas automatiquement persistés. Vous devez les uploader explicitement dans le stockage d’artefacts de GitHub ou vers Cloud Storage si vous voulez utiliser la sélection basée sur l’état de dbt (par exemple, dbt build --select state:modified) entre les exécutions.

Quand c’est le bon choix

Le scheduling GitHub Actions convient quand :

  • L’équipe est déjà sur GitHub et l’ajout d’infrastructure GCP n’est pas justifié
  • Le projet dbt a une exécution quotidienne (ou proche du quotidien) claire sans dépendances inter-jobs
  • La précision du timing dans une fenêtre de ±15 minutes est acceptable
  • Un coût mensuel supplémentaire nul est une contrainte
  • L’équipe est petite et déjà familière avec GitHub Actions

Quand choisir Cloud Run à la place

Cloud Run Jobs avec Cloud Scheduler devient le meilleur choix quand :

  • Vous avez besoin d’une logique de retry fiable sans code personnalisé
  • Votre pipeline a des dépendances sur d’autres jobs ou systèmes
  • Vous voulez un stockage persistant des artefacts entre les exécutions
  • La précision du timing est importante
  • Vous gérez déjà une infrastructure GCP

Les deux approches ne sont pas mutuellement exclusives. De nombreuses équipes commencent avec GitHub Actions et migrent vers Cloud Run quand les besoins évoluent. Le projet dbt lui-même ne change pas — seul ce qui invoque dbt build change. Le coût de migration est faible.

Pour une vue plus large de la place de cette approche dans l’espace décisionnel parmi toutes les options de scheduling natives GCP, le dbt Orchestration Decision Framework for GCP couvre la comparaison complète incluant Cloud Workflows pour les pipelines multi-étapes.