ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Configuration du compte de service dbt pour les architectures GCP multi-projets

Comment créer et configurer un compte de service dbt quand vos données sources, la sortie de transformation et l'infrastructure de calcul résident dans des projets GCP distincts.

Planté
dbtgcpbigquerydata engineeringautomation

La configuration typique d’un compte de service dbt suppose un seul projet GCP : dbt lit des tables, écrit des tables, tout dans un même endroit. Mais les architectures GCP réelles s’étendent souvent sur plusieurs projets — les données brutes dans les projets sources, la sortie de transformation dans un projet de transformation dédié, et l’infrastructure de calcul (Cloud Functions ou Cloud Run) potentiellement dans son propre projet.

Quand les projets se multiplient, la configuration IAM devient plus spécifique. Le compte de service a besoin de rôles différents dans chaque projet, et les commandes gcloud pour configurer cela sont fastidieuses à exécuter manuellement et faciles à mal configurer.

Le pattern à trois projets

La configuration courante pour une plateforme de données GCP avec Cloud Functions comporte trois projets jouant des rôles distincts :

Les projets sources hébergent les données brutes que dbt lit. Il peut s’agir d’un projet, ou de plusieurs si vos données proviennent de plusieurs équipes ou produits. Le compte de service dbt doit lire les données ici mais ne doit jamais rien écrire. Rôles nécessaires :

  • roles/bigquery.dataViewer — lire les données des tables
  • roles/bigquery.jobUser — exécuter des jobs de requêtes (le calcul BigQuery est facturé au projet où vous exécutez le job, pas où les données résident, donc vous avez besoin des permissions de job dans les projets sources si vous y interrogez des données)

Le projet de transformation héberge les datasets où dbt crée les tables et vues — vos couches base, intermediate et mart. Le compte de service a besoin d’un accès en écriture complet ici. Rôles nécessaires :

  • roles/bigquery.dataEditor — créer, mettre à jour et supprimer les tables et vues
  • roles/bigquery.user — exécuter des jobs et lister les datasets

Le projet de fonction est l’endroit où la Cloud Function s’exécute. Le compte de service a besoin de l’autorisation d’être invoqué en tant que Cloud Function. Rôles nécessaires :

  • roles/cloudfunctions.invoker — permet à Cloud Scheduler (ou d’autres appelants) de déclencher la fonction

Dans de nombreux déploiements, le projet de transformation et le projet de fonction sont identiques. Les maintenir séparés n’a de sens que si votre infrastructure est gérée au niveau de l’organisation avec des politiques strictes de projet par service.

Le script de configuration

Ce script gère tout ce qui précède depuis Cloud Shell. Définissez les variables pour votre environnement, puis exécutez-le une seule fois :

Terminal window
# Variables à configurer
TRANSFORM_PROJECT_ID="transform-project-id"
FUNCTION_PROJECT_ID="function-project-id"
SOURCE_PROJECT_IDS=("source-project-id-1" "source-project-id-2" "source-project-id-N")
SERVICE_ACCOUNT_NAME="dbt-transform-sa"
SERVICE_ACCOUNT_DISPLAY_NAME="dbt Transformation Service Account"
# Créer le compte de service dans le projet de transformations de données
gcloud iam service-accounts create "$SERVICE_ACCOUNT_NAME" \
--description="Service account for dbt data transformations" \
--display-name="$SERVICE_ACCOUNT_DISPLAY_NAME" \
--project="$TRANSFORM_PROJECT_ID"
# Formater l'email du compte de service
SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${TRANSFORM_PROJECT_ID}.iam.gserviceaccount.com"
echo "Compte de service $SERVICE_ACCOUNT_EMAIL créé."
# Boucler sur les IDs de projets sources pour attribuer les rôles
for PROJECT_ID in "${SOURCE_PROJECT_IDS[@]}"
do
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/bigquery.dataViewer"
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/bigquery.jobUser"
echo "Rôles attribués dans le projet source $PROJECT_ID."
done
# Attribuer les rôles dans le projet de transformation
gcloud projects add-iam-policy-binding "$TRANSFORM_PROJECT_ID" \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/bigquery.dataEditor"
gcloud projects add-iam-policy-binding "$TRANSFORM_PROJECT_ID" \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/bigquery.user"
echo "Rôles attribués dans le projet de transformation."
# Attribuer le rôle Cloud Function Invoker dans le projet où la Cloud Function s'exécutera
gcloud projects add-iam-policy-binding "$FUNCTION_PROJECT_ID" \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/cloudfunctions.invoker"
echo "Rôle Cloud Function Invoker attribué."
echo "Configuration terminée."

Le compte de service est créé dans le projet de transformation, ce qui est un emplacement raisonnable — c’est là que se passe l’essentiel de son travail. De là, il se voit accorder des rôles dans chaque projet source via des liaisons IAM cross-projets, ce qui est un pattern GCP standard.

Pourquoi ne pas utiliser un seul projet ?

Si vous lisez ceci et que votre configuration est un seul projet, vous n’avez pas besoin de toute cette complexité. Créez un compte de service, donnez-lui bigquery.dataEditor et bigquery.jobUser sur le projet, et vous avez terminé.

La configuration multi-projets est importante quand :

  • La propriété des données est distribuée. Différentes équipes possèdent leurs données brutes dans des projets séparés et contrôlent qui peut les lire. Votre compte de service dbt obtient un accès explicite aux datasets dont il a besoin, sans accès général à tout.
  • La facturation est séparée. Les coûts de requêtes dans GCP sont facturés au projet qui exécute la requête. Si le calcul data engineering doit apparaître séparément des coûts produit ou analytique, exécuter les requêtes depuis un projet de transformation dédié isole ces coûts.
  • Les frontières de sécurité sont imposées au niveau de l’organisation. Certaines organisations exigent que les données de production résident dans des projets avec des contrôles plus stricts que ceux utilisés au quotidien par les data engineers. Les données sources restent dans un projet sécurisé ; le compte de service n’obtient que l’accès en lecture à ce dont dbt a réellement besoin.

La note Patterns IAM BigQuery couvre le modèle de permissions sous-jacent — la séparation entre les rôles d’accès aux données et les rôles de calcul — plus en profondeur. Le pattern multi-projets ici est une application de ces principes à travers les frontières de projets.

Attacher le compte de service

Lors du déploiement de la Cloud Function, attachez le compte de service explicitement :

Terminal window
gcloud functions deploy dbt_run \
--region=europe-west1 \
--service-account=dbt-transform-sa@transform-project-id.iam.gserviceaccount.com \
--gen2 \
--runtime=python310 \
--entry-point=run_dbt \
--trigger-http \
--timeout=3500 \
--memory=1G

Le flag --service-account définit l’identité sous laquelle la fonction s’exécute. Avec method: oauth dans profiles.yml, dbt-bigquery récupère cette identité via les Application Default Credentials automatiquement — aucun fichier de clé n’est nécessaire.

Pour les Cloud Run Jobs pour dbt, le flag équivalent est --service-account sur gcloud run jobs create. Les exigences de rôle IAM sont similaires mais légèrement différentes : au lieu de roles/cloudfunctions.invoker, le compte de service du planificateur a besoin de roles/run.invoker sur le Cloud Run Job. Le pattern sous-jacent — permissions en lecture seule séparées sur les projets sources, permissions en écriture sur le projet de transformation — est identique.