AccueilBlogStack dbt + Snowflake : architecture complète en production
Guide recrutement data

Stack dbt + Snowflake : architecture complète en production

dbt et Snowflake forment la stack analytique la plus répandue en 2025. En entretien Senior, on évalue la capacité à architecturer cette stack de manière robuste, testée et économique.

Data Builder·Juin 2025·7 min de lecture·Analytics Engineer
Sommaire
  1. Architecture de référence
  2. Organisation des modèles dbt
  3. Optimisation Snowflake
  4. CI/CD slim
  5. Maîtrise des coûts
  6. Gouvernance et documentation
  7. Grille

1Architecture de référence dbt + Snowflake

Question discriminante

Décrivez l architecture complète d une stack dbt + Snowflake bien structurée.

# Architecture dbt + Snowflake de référence SNOWFLAKE ├── RAW_DB # données brutes, jamais modifiées │ ├── FIVETRAN/ # ingestion via Fivetran │ └── AIRBYTE/ # ingestion via Airbyte ├── DEV_DB # environnement de développement │ └── ANALYTICS/ # schémas dbt dev (par développeur) └── PROD_DB # production ├── STAGING/ # modèles staging dbt ├── INTERMEDIATE/# modèles intermédiaires └── MARTS/ # tables consommées par la BI # dbt profiles.yml my_project: target: dev outputs: dev: type: snowflake account: mon_compte database: DEV_DB schema: '{{ env_var("DBT_SCHEMA", "analytics_" ~ env_var("USER")) }}' warehouse: DEV_WH prod: database: PROD_DB schema: MARTS warehouse: PROD_WH
  • Séparation RAW/DEV/PROD — les données brutes ne sont jamais modifiées. Les développeurs travaillent dans leur propre schéma
  • Schema par développeur — chaque dev a son schéma isolé en DEV. Évite les conflits

2Organisation des modèles dbt

Question discriminante

Comment organisez-vous staging, intermediate et marts dans un projet dbt ?

# dbt_project.yml - configuration par layer models: mon_projet: staging: +schema: staging +materialized: view # vues légères +tags: ['staging'] intermediate: +schema: intermediate +materialized: view +tags: ['intermediate'] marts: +schema: marts +materialized: table # tables pour la BI finance: +materialized: table marketing: +materialized: table +tags: ['marts'] seeds: +schema: seeds +tags: ['seed']
  • Staging — 1 modèle par table source, renommage, cast, pas de logique métier
  • Intermediate — jointures et logique métier partagée entre plusieurs marts
  • Marts — tables finales orientées métier, consommées par Power BI/Tableau/Looker
  • Matérialisations — vues pour staging/intermediate (pas de stockage), tables pour les marts (performance BI)

3Optimisation Snowflake pour dbt

Question discriminante

Quels paramètres Snowflake optimisez-vous pour vos modèles dbt ?

-- Cluster Key sur les grandes tables marts ALTER TABLE PROD_DB.MARTS.FCT_ORDERS CLUSTER BY (order_date, region); -- Incremental model dbt optimisé {{ config( materialized='incremental', unique_key='order_id', cluster_by=['order_date'], on_schema_change='append_new_columns', snowflake_warehouse='TRANSFORM_WH_M' ) }} SELECT * FROM {{ ref('stg_orders') }} {% if is_incremental() %} WHERE order_date > (SELECT MAX(order_date) FROM {{ this }}) {% endif %}
  • Incremental models — ne retraiter que les nouvelles données. Réduit le compute de 90%+ sur les grandes tables
  • Warehouse sizing — utiliser un petit warehouse (XS-S) pour les modèles légers, un plus grand (M-L) pour les transformations lourdes
  • Query tags — taguer les requêtes dbt avec le nom du modèle pour l attribution des coûts

4CI/CD : slim CI dbt sur Snowflake

Question discriminante

Comment mettez-vous en place le slim CI dbt pour limiter les coûts Snowflake en CI ?

# .github/workflows/dbt-ci.yml jobs: dbt_slim_ci: steps: - name: dbt build (models modifiés uniquement) run: | dbt build \ --select state:modified+ \ --defer \ --state ./prod-artifacts \ --target ci \ --exclude tag:slow env: SNOWFLAKE_ACCOUNT: ${{ secrets.SF_ACCOUNT }} SNOWFLAKE_USER: ${{ secrets.SF_USER }} SNOWFLAKE_PASSWORD: ${{ secrets.SF_PASSWORD }} - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: dbt-artifacts path: target/manifest.json
  • state:modified+ — rebuild uniquement les modèles changés et leurs descendants
  • --defer — utiliser les relations de PROD pour les modèles non modifiés. Pas besoin de rebuilder toute la stack
  • CI warehouse — utiliser un XS warehouse dédié pour la CI. Arrêter après chaque run

5Maîtrise des coûts Snowflake + dbt

Question discriminante

Comment réduisez-vous les coûts Snowflake de vos pipelines dbt ?

  • Incremental models — premier levier. Éviter les full refresh sur les grandes tables
  • Auto-suspend agressif — 1 minute de suspension pour les warehouses dbt (les jobs sont courts)
  • Warehouse par use case — un warehouse pour la CI (XS), un pour les transformations quotidiennes (S-M), un pour la BI (XS avec cache)
  • INFORMATION_SCHEMA monitoring — suivre les credits consommés par modèle dbt via query_tag
  • Éviter SELECT * — toujours sélectionner les colonnes nécessaires dans les modèles dbt

6Gouvernance : documentation et lineage

Question discriminante

Comment assurez-vous que votre projet dbt reste maintenable dans le temps ?

  • Descriptions obligatoires — configurer dbt pour forcer la documentation des colonnes clés via pre-commit hooks
  • Exposures — documenter qui consomme chaque modèle (dashboards Power BI, APIs, rapports automatiques)
  • dbt docs — générer et publier la documentation automatiquement à chaque merge sur main
  • Elementary — package de data observabilité pour monitorer la qualité des données en production
  • Conventions de nommage — stg_ pour staging, int_ pour intermediate, fct_ et dim_ pour les marts
# profiles.yml Snowflake multi-env my_project: target: dev outputs: dev: type: snowflake account: myorg.snowflakecomputing.com user: "{{ env_var('SNOWFLAKE_USER') }}" private_key_path: "{{ env_var('SNOWFLAKE_PRIVATE_KEY_PATH') }}" role: TRANSFORMER_DEV database: DEV_DB warehouse: TRANSFORM_WH_XS schema: "dbt_{{ env_var('USER', 'dev') }}" threads: 4 prod: type: snowflake account: myorg.snowflakecomputing.com user: dbt_prod_svc private_key_path: /secrets/snowflake_pk.p8 role: TRANSFORMER_PROD database: PROD_DB warehouse: TRANSFORM_WH_M schema: analytics threads: 16 # dbt_project.yml optimisations Snowflake models: my_project: staging: +materialized: view marts: +materialized: table +snowflake_warehouse: TRANSFORM_WH_L +post-hook: "GRANT SELECT ON {{ this }} TO ROLE REPORTER"
  • Key pair authentication - privilegier la cle privee RSA plutot que mot de passe pour les comptes de service. Plus securise, supporte par les secrets managers
  • Warehouse sizing par couche - staging/intermediate sur XS (views legeres), marts sur M ou L pour les tables materialisees
  • Dynamic tables vs dbt incremental - pour les agregations simples, les Snowflake Dynamic Tables remplacent avantageusement dbt incremental : zero orchestration externe
  • Cloning pour les tests - CREATE DATABASE dev_clone CLONE production avant les tests de migration. Zero-copy, instantane, sans impacter la prod
  • COPY INTO vs INSERT - charger de gros volumes dans Snowflake via COPY INTO depuis S3/GCS. 10-100x plus rapide que des INSERT en batch

7Grille par niveau

NiveauMaitriseSignal GONO-GO
ConfirméStructure staging/marts, tests, déploiement manuelA structuré un projet dbt en 3 layers, a configuré Snowflake warehousesMet toute la logique dans les marts sans staging
SeniorIncremental models, slim CI, coûts maîtrisés, gouvernanceA mis en place le slim CI, utilise des incremental models, monitore les coûtsNe sait pas ce qu est un incremental model, ne connaît pas le slim CI

Vous recrutez un Analytics Engineer dbt + Snowflake ?

Premier entretien gratuit. Rapport GO/NO-GO sous 48h.