dbt

Junior

¿Cómo configuro profiles.yml de dbt para que las credenciales nunca terminen en git?

dbt separa a propósito "qué construir" de "dónde conectarse" en dos archivos - uno se commitea, el otro nunca debería. Así es como se supone que funciona esa separación.

Leer en:
Hardcodeado en profiles.yml Archivo .env commiteado Filtrado en logs de CI
Formas comunes en que las credenciales del warehouse terminan donde no deberían, aproximadamente en ese orden - no un desglose medido.

dbt_project.yml describe su proyecto y vive en git. profiles.yml describe cómo conectarse a un warehouse y, por defecto, vive completamente fuera de cualquier repositorio. Confundir los dos es la forma más común en que las credenciales terminan commiteadas.

Dónde vive profiles.yml, y por qué no es un accidente

Por defecto dbt busca profiles.yml en ~/.dbt/ - no en el directorio de su proyecto, y no algo que dbt init ponga bajo control de versiones. Puede apuntarlo a otro lugar con la variable de entorno DBT_PROFILES_DIR (útil en CI, donde no hay directorio home del que hablar), pero la ubicación por defecto es todo el punto: mantiene los detalles de conexión físicamente separados del código que se sube a GitHub.

# ~/.dbt/profiles.yml - nunca dentro del propio proyecto dbt my_project: target: dev outputs: dev: type: snowflake account: "{{ env_var('DBT_ACCOUNT') }}" user: "{{ env_var('DBT_USER') }}" password: "{{ env_var('DBT_PASSWORD') }}" role: transformer database: analytics warehouse: transforming schema: dbt_dev threads: 4

La clave my_project: de arriba tiene que coincidir con el valor profile: en su dbt_project.yml - ese es el único vínculo entre los dos archivos, y es un nombre, no un secreto.

env_var() es todo el truco

Todo valor que no debería ser legible por quien pueda hacer cat del archivo pasa por env_var('SOME_NAME') en vez de escribirse literalmente. En local, eso significa exportar la variable en su perfil de shell o en un archivo .env local que esté en .gitignore (direnv o dotenv funcionan bien para esto). En CI, significa configurar los mismos nombres como secretos cifrados en lo que sea que ejecute sus jobs de dbt - secretos de GitHub Actions, conexiones de Airflow, o el equivalente de su orquestador - nunca como texto plano en un archivo de workflow.

La parte que se saltan: env_var() toma un segundo argumento opcional como valor por defecto - env_var('DBT_THREADS', '4') - lo cual está bien para configuraciones que no son secretas, pero omitirlo en una variable de contraseña hace que un secreto faltante falle ruidosamente con "env var required but not provided" en vez de conectarse silenciosamente como otro usuario. No le dé valores por defecto a los secretos.

Dónde esto sigue fallando

Dos brechas reales que esto no cierra por sí solo. Primero, nada impide que un compañero agregue un segundo bloque target con una contraseña literal "solo por ahora" - profiles.yml no es linteado por dbt mismo, así que esto necesita un hábito de revisión de código, no solo una plantilla. Segundo, dbt debug solo valida el target al que está apuntando actualmente; un typo en un target que rara vez usa (un output staging ocasional, digamos) puede quedar roto durante meses hasta que alguien finalmente lo ejecute. Ninguno de los dos es un problema de dbt para arreglar - opti-pipe no toca credenciales ni configuración de conexión en absoluto, solo el run_results.json que un run produce después de haberse conectado exitosamente.

Vea cómo se ve esto en su propio pipeline.

Suba un event log real de Spark, un run_results.json de dbt o una exportación de métricas de Flink y obtenga recomendaciones concretas, que debe aprobar antes de aplicar - no otra regla general.