dbt
JuniorКак настроить profiles.yml в dbt так, чтобы креды никогда не попадали в git?
dbt намеренно разделяет «что строить» и «куда подключаться» на два файла — один коммитится, второй не должен коммититься никогда. Вот как это разделение должно работать.
dbt_project.yml описывает ваш проект и лежит в git. profiles.yml описывает подключение к хранилищу и по умолчанию лежит вообще вне любого репозитория. Смешение этих двух файлов — самая частая причина, по которой креды оказываются закоммичены.
Где лежит profiles.yml и почему это не случайность
По умолчанию dbt ищет profiles.yml в ~/.dbt/ — не в директории проекта, и не в том,
что dbt init кладёт под контроль версий. Можно указать другое расположение через переменную
окружения DBT_PROFILES_DIR (полезно в CI, где домашней директории как таковой нет), но
расположение по умолчанию — это и есть смысл: оно физически отделяет данные подключения от кода, который
пушится в GitHub.
Ключ my_project: сверху должен совпадать со значением profile: в вашем
dbt_project.yml — это единственная связь между двумя файлами, и это имя, а не секрет.
env_var() — это и есть весь трюк
Любое значение, которое не должно быть читаемо тем, кто может сделать cat файла, идёт через
env_var('SOME_NAME') вместо того, чтобы быть вписанным буквально. Локально это означает экспорт
переменной в профиле shell'а или в локальном .env файле, который в .gitignore
(direnv или dotenv отлично для этого подходят). В CI это означает установку тех же
имён как зашифрованных секретов в том, что запускает ваши задачи dbt — секреты GitHub Actions, коннекшены
Airflow или эквивалент вашего оркестратора — никогда как открытый текст в файле workflow.
Что часто пропускают: у env_var() есть необязательный второй аргумент как значение
по умолчанию — env_var('DBT_THREADS', '4') — это нормально для несекретных настроек, но если
не задать его для переменной с паролем, отсутствующий секрет громко упадёт с ошибкой «env var required but
not provided» вместо тихого подключения от имени какого-то другого пользователя. Не давайте секретам
значения по умолчанию.
Где это всё ещё ломается
Два реальных пробела, которые это само по себе не закрывает. Во-первых, ничто не мешает коллеге
добавить второй блок target с буквальным паролем «просто пока» — profiles.yml сам по себе
dbt не линтует, так что тут нужна привычка код-ревью, а не только шаблон. Во-вторых, dbt debug
проверяет только тот target, на который вы сейчас указываете; опечатка в редко используемом target
(например, разовый output staging) может лежать сломанной месяцами, пока кто-то наконец не
запустит его. Ни то, ни другое — не проблема dbt, которую нужно чинить: opti-pipe вообще не трогает креды
или конфиг подключения, только run_results.json, который прогон производит уже после того, как
успешно подключился.
Посмотрите, как это выглядит на вашем собственном пайплайне.
Загрузите реальный event log Spark, run_results.json от dbt или экспорт метрик Flink — и получите конкретные рекомендации, которые нужно одобрить, а не ещё одно эмпирическое правило.