dbt

Junior

Como configuro o profiles.yml do dbt para que credenciais nunca acabem no git?

O dbt separa de propósito "o que construir" de "onde se conectar" em dois arquivos - um é commitado, o outro nunca deveria ser. Veja como essa separação deveria funcionar.

Ler em:
Hardcoded no profiles.yml Arquivo .env commitado Vazado nos logs do CI
Formas comuns pelas quais credenciais de warehouse acabam onde não deveriam, aproximadamente nessa ordem - não um levantamento medido.

O dbt_project.yml descreve seu projeto e vive no git. O profiles.yml descreve como se conectar a um warehouse e, por padrão, vive completamente fora de qualquer repositório. Confundir os dois é a forma mais comum de credenciais acabarem commitadas.

Onde o profiles.yml vive, e por que isso não é acidente

Por padrão o dbt procura o profiles.yml em ~/.dbt/ - não no diretório do seu projeto, e não algo que o dbt init coloca sob controle de versão. Você pode apontar para outro lugar com a variável de ambiente DBT_PROFILES_DIR (útil em CI, onde não há diretório home para falar a verdade), mas o local padrão é todo o ponto: ele mantém os detalhes de conexão fisicamente separados do código que é enviado ao GitHub.

# ~/.dbt/profiles.yml - nunca dentro do próprio projeto 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

A chave my_project: no topo precisa bater com o valor profile: no seu dbt_project.yml - esse é o único vínculo entre os dois arquivos, e é um nome, não um segredo.

env_var() é todo o truque

Todo valor que não deveria ser legível por quem consegue dar cat no arquivo passa por env_var('SOME_NAME') em vez de ser digitado literalmente. Localmente, isso significa exportar a variável no seu perfil de shell ou em um arquivo .env local que esteja no .gitignore (direnv ou dotenv funcionam bem para isso). No CI, isso significa configurar os mesmos nomes como secrets criptografados em o que quer que rode seus jobs do dbt - secrets do GitHub Actions, conexões do Airflow, ou o equivalente do seu orquestrador - nunca como texto puro em um arquivo de workflow.

A parte que costuma ser pulada: env_var() aceita um segundo argumento opcional como valor padrão - env_var('DBT_THREADS', '4') - o que é aceitável para configurações que não são segredo, mas deixar isso de fora de uma variável de senha faz com que um secret ausente falhe bem alto com "env var required but not provided" em vez de conectar silenciosamente como outro usuário. Não dê valores padrão a segredos.

Onde isso ainda dá errado

Duas lacunas reais que isso não fecha sozinho. Primeiro, nada impede um colega de adicionar um segundo bloco target com uma senha literal "só por enquanto" - o profiles.yml não é lintado pelo próprio dbt, então isso precisa de um hábito de code review, não só de um template. Segundo, o dbt debug só valida o target que você está apontando no momento; um erro de digitação em um target raramente usado (um output staging ocasional, digamos) pode ficar quebrado por meses até alguém finalmente rodar contra ele. Nenhum dos dois é um problema do dbt para resolver - o opti-pipe não mexe em credenciais ou configuração de conexão de forma alguma, apenas no run_results.json que um run produz depois de já ter se conectado com sucesso.

Veja como isso fica no seu próprio pipeline.

Envie um event log real do Spark, um run_results.json do dbt ou uma exportação de métricas do Flink e receba recomendações concretas, para aprovar antes de aplicar - não mais uma regra geral.