Les ressources sont le mécanisme de Dagster pour gérer les connexions externes. Un BigQueryResource, un DbtCliResource, un client GCS, une clé API — tout ce dont les assets ont besoin pour interagir avec le monde extérieur est configuré comme une ressource. Les ressources sont définies centralement dans l’objet Definitions et injectées dans les assets à l’exécution.
Le code des assets déclare quelles ressources il nécessite via des arguments de fonction annotés par type ; Dagster fournit la bonne instance selon l’environnement. L’asset ne construit pas sa propre connexion à la base de données ni ne lit directement les variables d’environnement.
Le pattern de base
Les ressources sont configurées une fois dans Definitions et injectées dans tout asset qui les demande :
import dagster as dgfrom dagster_dbt import DbtCliResourcefrom dagster_gcp import BigQueryResource
defs = dg.Definitions( assets=[mrt__finance__daily_revenue, my_dbt_assets], resources={ "bigquery": BigQueryResource(project="my-gcp-project"), "dbt": DbtCliResource(project_dir="./transform"), },)Un asset demande une ressource en l’ajoutant comme argument annoté par type :
@dg.assetdef mrt__finance__daily_revenue( context: dg.AssetExecutionContext, bigquery: BigQueryResource,) -> None: client = bigquery.get_client() # Utiliser le client BigQuery pour écrire les résultats client.query("INSERT INTO ...").result()Dagster fait correspondre le nom d’argument bigquery à la clé "bigquery" dans le dictionnaire de ressources. L’asset reçoit l’instance BigQueryResource configurée sans savoir comment elle a été configurée. Cette indirection est tout l’intérêt : la logique de l’asset ne change pas quand les détails de connexion changent.
Changement d’environnement
Le principal avantage pratique des ressources est la gestion des environnements. Les environnements de développement, staging et production diffèrent typiquement sur :
- Le projet GCP ou le dataset BigQuery à cibler
- Les identifiants du compte de service à utiliser
- L’utilisation d’un profil dbt de test ou du profil de production
- Les tailles de pool de connexion, timeouts, politiques de retry
Avec les ressources, on change d’environnement en modifiant la configuration Definitions, pas le code des assets :
import os
env = os.getenv("DAGSTER_ENV", "dev")
if env == "prod": bq_resource = BigQueryResource(project="prod-gcp-project") dbt_resource = DbtCliResource( project_dir="./transform", target="prod", )else: bq_resource = BigQueryResource(project="dev-gcp-project") dbt_resource = DbtCliResource( project_dir="./transform", target="dev", )
defs = dg.Definitions( assets=[...], resources={ "bigquery": bq_resource, "dbt": dbt_resource, },)C’est le même principe que celui derrière le profiles.yml dbt avec plusieurs targets — mais appliqué à chaque connexion externe du pipeline, pas seulement à la base de données. Les assets dbt, les assets d’extraction Python et les assets de notification en aval obtiennent tous des connexions adaptées à l’environnement depuis la même configuration centralisée.
Pour les équipes exécutant dbt sur BigQuery avec des datasets dev et prod séparés, les ressources s’alignent naturellement. Le DbtCliResource avec target="dev" pointe dbt vers le dataset de développement. Le BigQueryResource pour les assets Python pointe vers le même projet. Tout reste cohérent sans IDs de projet codés en dur dispersés dans les fichiers d’assets.
Ressources courantes pour les analytics engineers
Les ressources les plus susceptibles d’être utilisées dans un pipeline dbt + BigQuery + GCP :
DbtCliResource
Le pont entre Dagster et le projet dbt. Configuré avec le répertoire du projet et optionnellement la target, le profil et les flags CLI :
from dagster_dbt import DbtCliResource
dbt_resource = DbtCliResource( project_dir="./transform", target="prod", profiles_dir="./transform",)Cette ressource est ce que le décorateur @dbt_assets utilise en interne pour exécuter dbt build. Quand dbt.cli(["build"], context=context) est appelé à l’intérieur de la fonction des assets dbt, c’est cette ressource qui est utilisée.
BigQueryResource
Pour les assets Python qui lisent depuis ou écrivent dans BigQuery directement (pas via dbt) :
from dagster_gcp import BigQueryResource
bq_resource = BigQueryResource( project="my-gcp-project", location="US",)Utile pour les assets qui font des choses que le SQL ne peut pas faire : appeler des APIs externes, exécuter une inférence ML, générer des fichiers. L’asset lit depuis BigQuery via la ressource, traite en Python, et renvoie les résultats.
Ressource GCS
Pour les assets qui interagissent avec Cloud Storage — lire des fichiers bruts, écrire des exports, mettre en staging des données pour les chargements BigQuery :
from dagster_gcp import GCSResource
gcs_resource = GCSResource( project="my-gcp-project",)EnvVar pour les secrets
Dagster fournit dg.EnvVar pour lire les secrets depuis les variables d’environnement à l’exécution plutôt qu’à la définition. C’est important pour le déploiement où les secrets proviennent de Secret Manager ou des secrets Kubernetes :
defs = dg.Definitions( resources={ "bigquery": BigQueryResource( project=dg.EnvVar("GCP_PROJECT"), ), },)EnvVar lit la variable d’environnement quand la ressource est instanciée à l’exécution, pas quand le module Python est importé. Cela empêche les secrets de fuiter dans les journaux ou d’être requis au démarrage de dagster dev.
Ressources vs connexions codées en dur
Sans ressources, la tentation est de créer des connexions en ligne :
# Ne pas faire ça@dg.assetdef my_asset(): from google.cloud import bigquery client = bigquery.Client(project="prod-gcp-project") # Codé en dur ! ...Ça fonctionne mais crée des problèmes :
- Couplage à l’environnement. L’asset cible toujours la production. L’exécuter en développement nécessite de modifier le code.
- Friction de test. Les tests unitaires ne peuvent pas facilement substituer un client mock.
- Prolifération des connexions. Chaque asset crée son propre client avec sa propre configuration. Les pools de connexion, les retries et les timeouts sont configurés de façon incohérente.
- Gestion des secrets. Les clés API et les identifiants se retrouvent dans le code source ou dispersés à travers les lectures de variables d’environnement.
Les ressources centralisent tout ça. Un seul endroit pour configurer, un seul endroit pour modifier, un seul endroit à auditer pour la sécurité.
Ressources et composants
L’abstraction Components utilise intensément les ressources. Quand un DbtProjectComponent est scaffoldé, le DbtCliResource est configuré en YAML plutôt qu’en Python :
type: dagster_dbt.DbtProjectComponentparams: project_dir: ./transform dbt: target: prodSous le capot, le composant crée et enregistre le DbtCliResource automatiquement. C’est une partie de la façon dont les Components réduisent le boilerplate Python — la configuration des ressources passe du code Python au YAML déclaratif, correspondant à la philosophie configuration-over-code à laquelle les analytics engineers sont habitués avec dbt_project.yml et profiles.yml.
Le modèle mental
En venant de dbt, penser aux ressources comme l’équivalent Dagster de profiles.yml — mais généralisé à chaque système externe, pas seulement à la base de données. Le profil définit où se connecter (projet, dataset, identifiants). Le modèle définit ce que produire (le SQL, les dépendances). Les ressources maintiennent cette même séparation à travers l’intégralité du pipeline, pas seulement la portion dbt.