ServicesÀ proposNotesContact Me contacter →
EN FR
Note

dbt profiles.yml avec env_var pour GCP multi-client

Utiliser l'interpolation env_var() dans profiles.yml pour que dbt lise les credentials et le projet GCP depuis des variables d'environnement — permettant un changement de client transparent via direnv.

Planté
dbtgcpbigquerydata engineeringautomation

Le profiles.yml de dbt supporte la fonction env_var() de Jinja pour lire des variables d’environnement à l’exécution. Combiné avec direnv, cela signifie qu’un seul profiles.yml peut servir chaque projet client — dbt récupère les bons credentials et le bon projet selon le répertoire dans lequel vous vous trouvez quand vous l’exécutez.

Le pattern central

Chaque client obtient son propre bloc de profil dans ~/.dbt/profiles.yml. Au lieu de coder les credentials en dur, chaque valeur spécifique au client est lue depuis des variables d’environnement :

~/.dbt/profiles.yml
acme_analytics:
target: "{{ env_var('DBT_TARGET', 'dev') }}"
outputs:
dev:
type: bigquery
method: service-account
project: "{{ env_var('GOOGLE_CLOUD_PROJECT') }}"
dataset: dbt_dev
keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}"
threads: 4
location: EU
prod:
type: bigquery
method: service-account
project: "{{ env_var('GOOGLE_CLOUD_PROJECT') }}"
dataset: analytics
keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}"
threads: 8
location: EU
globex_warehouse:
target: "{{ env_var('DBT_TARGET', 'dev') }}"
outputs:
dev:
type: bigquery
method: service-account
project: "{{ env_var('GOOGLE_CLOUD_PROJECT') }}"
dataset: dbt_dev
keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}"
threads: 4
location: US
prod:
type: bigquery
method: service-account
project: "{{ env_var('GOOGLE_CLOUD_PROJECT') }}"
dataset: analytics
keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}"
threads: 8
location: US

Chaque profil lit depuis les mêmes variables d’environnement : GOOGLE_CLOUD_PROJECT, GOOGLE_APPLICATION_CREDENTIALS et DBT_TARGET. direnv définit des valeurs différentes pour ces variables dans chaque répertoire client. Quand vous changez de répertoire, dbt cible automatiquement un projet différent avec des credentials différents.

Fonctionnement du changement

Dans le répertoire du Client A :

Terminal window
# direnv charge :
export GOOGLE_CLOUD_PROJECT=acme-analytics-prod
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.gcp-keys/acme-dbt-runner.json"
export DBT_TARGET=prod
dbt run --profile acme_analytics
# Lit GOOGLE_CLOUD_PROJECT → acme-analytics-prod
# Utilise le keyfile depuis GOOGLE_APPLICATION_CREDENTIALS → clé acme
# Cible la sortie prod car DBT_TARGET=prod

Dans le répertoire du Client B :

Terminal window
# direnv charge des valeurs différentes :
export GOOGLE_CLOUD_PROJECT=globex-warehouse-prod
export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.gcp-keys/globex-dbt-runner.json"
export DBT_TARGET=prod
dbt run --profile globex_warehouse
# Lit GOOGLE_CLOUD_PROJECT → globex-warehouse-prod
# Utilise le keyfile depuis GOOGLE_APPLICATION_CREDENTIALS → clé globex
# Même commande, client différent

Les noms de profils (acme_analytics, globex_warehouse) sont statiques — vous les référencez dans dbt_project.yml. Les credentials qu’ils utilisent sont dynamiques, pilotés par les variables d’environnement.

Méthode d’auth : pourquoi service-account plutôt qu’oauth

Deux méthodes sont couramment utilisées pour les connexions BigQuery dans dbt :

method: oauth utilise votre identité Google personnelle via les Application Default Credentials. Cela fonctionne bien pour le développement sur un projet unique et est la recommandation par défaut dans le quickstart BigQuery de dbt.

method: service-account utilise un fichier de clé de compte de service explicite via la propriété keyfile. C’est le choix adapté au conseil.

Le problème avec oauth dans une configuration multi-client est qu’il repose sur le fichier ADC (~/.config/gcloud/application_default_credentials.json), géré par gcloud et lié à votre session OAuth personnelle. Gérer quel fichier ADC est actif sur plusieurs clients est compliqué — c’est l’une des choses que CLOUDSDK_CONFIG pour l’isolation gcloud par projet résout, mais même avec l’isolation, les sessions ADC peuvent expirer et nécessiter une ré-authentification via le navigateur.

La méthode oauth casse aussi complètement dans les environnements non-interactifs : pipelines CI/CD, conteneurs et sessions d’agents IA qui ne peuvent pas effectuer de flux de navigateur.

service-account avec env_var('GOOGLE_APPLICATION_CREDENTIALS') fonctionne dans chaque contexte. Le fichier de clé est explicite, durable et ne nécessite pas de ré-authentification interactive. Il hérite le chemin des variables d’environnement, que direnv gère. Et il fonctionne de manière identique que vous exécutiez dbt run manuellement, depuis une Cloud Function ou dans une session Claude Code.

La valeur par défaut de env_var

env_var() accepte un deuxième argument optionnel comme valeur par défaut :

target: "{{ env_var('DBT_TARGET', 'dev') }}"

Cela signifie que si DBT_TARGET n’est pas défini (ex. : vous travaillez en dehors d’un répertoire géré par direnv), dbt retombe sur la cible dev. C’est un filet de sécurité : mieux vaut exécuter accidentellement dev que d’exécuter accidentellement prod.

Pour GOOGLE_CLOUD_PROJECT et GOOGLE_APPLICATION_CREDENTIALS, ne fournissez pas de valeurs par défaut. Si ces variables ne sont pas définies, vous voulez que dbt échoue bruyamment avec une erreur de variable manquante plutôt que d’utiliser silencieusement un credential global obsolète.

Emplacement du fichier profiles

Par défaut, dbt cherche profiles.yml dans ~/.dbt/. Vous pouvez remplacer cela avec --profiles-dir ou la variable d’environnement DBT_PROFILES_DIR.

Pour les configurations de conseil, un seul ~/.dbt/profiles.yml avec tous les profils clients est généralement l’approche la plus propre. Les blocs de profil sont statiques (uniquement les noms et la configuration non-credentials comme threads et location) ; les credentials eux-mêmes proviennent des variables d’environnement.

Une alternative est de conserver profiles.yml à l’intérieur du dépôt du projet et de l’inclure dans .gitignore. Cela fonctionne si vous voulez que la définition du profil vive avec le code. Le pattern env_var s’applique dans les deux cas — vous définissez simplement DBT_PROFILES_DIR sur le répertoire du projet au lieu de cela.

Compatibilité CI/CD

Le même profiles.yml fonctionne en CI/CD sans modification. Votre pipeline CI définit GOOGLE_CLOUD_PROJECT, GOOGLE_APPLICATION_CREDENTIALS et DBT_TARGET comme secrets ou variables d’environnement du pipeline. dbt les lit de manière identique à la façon dont il les lit localement depuis direnv.

C’est le principal bénéfice du pattern : le développement local et le CI/CD utilisent le même mécanisme de configuration. Il n’y a pas de profiles.yml séparé pour le local et la production, pas de logique conditionnelle, pas de fichiers spécifiques à l’environnement à maintenir synchronisés.