Guides
Apache Airflow

Airflow connections: как не хранить пароли в DAG

Управление Connections в Airflow: UI, CLI, переменные среды (AIRFLOW_CONN_*), Secrets Backend (Vault, AWS SSM). Как пере

Если вы хоть раз коммитили DAG с зашитым в него паролем от продовой базы — вы не одиноки. Но после этого обычно наступает холодный пот и мысль «надо срочно всё переделать». Хранить креденшелы в коде — это билет в один конец к компрометации данных. К счастью, Airflow предлагает несколько встроенных механизмов для безопасной работы с подключениями. Разберём их по нарастающей сложности и безопасности.

Способ 1: Connections в UI — для локальной разработки

Самый простой и известный метод — создать connection через веб-интерфейс (Admin -> Connections). DAG при этом ссылается только на conn_id.

from airflow.providers.postgres.hooks.postgres import PostgresHook

def query_data():
    hook = PostgresHook(postgres_conn_id='my_prod_db')
    conn = hook.get_conn()
    # работа с соединением

Плюс: быстро и наглядно. Минус: пароли хранятся в базе Airflow. При резервном копировании метаданных они тоже уезжают. Не подходит для командной работы или продакшена.

Способ 2: CLI — для автоматизации

Добавлять и обновлять подключения можно через CLI, что удобно для скриптов развертывания.

airflow connections add 'my_prod_db' \
    --conn-type 'postgres' \
    --conn-host 'localhost' \
    --conn-login 'user' \
    --conn-password 'pass' \
    --conn-port 5432

Но пароль снова оказывается в истории командной строки. Можно передать его через --conn-password $DB_PASS, но корень проблемы тот же.

Способ 3: Переменные окружения AIRFLOW_CONN_*

Мощный и часто недооценённый способ. Airflow автоматически создаёт connection, если найдёт переменную окружения с именем AIRFLOW_CONN_<CONN_ID> в верхнем регистре. Значение — URI подключения.

export AIRFLOW_CONN_MY_PROD_DB='postgres://user:password@localhost:5432/dbname'

В коде DAG обращаемся как обычно к conn_id='my_prod_db'. Особенно удобно в Docker и Kubernetes: подставляйте секреты через механизмы контейнерной платформы (Kubernetes Secrets, Docker Secrets). Пароли никогда не попадают в код или базу Airflow.

Способ 4: Secrets Backend — продакшен-решение

Для серьёзных инсталляций используйте внешние хранилища секретов: HashiCorp Vault, AWS SSM Parameter Store, AWS Secrets Manager, GCP Secret Manager. Конфигурация задаётся в airflow.cfg или через env-переменные.

Пример для HashiCorp Vault:

[secrets]
backend = airflow.providers.hashicorp.secrets.vault.VaultBackend
backend_kwargs = {"connections_path": "airflow/connections", "url": "http://127.0.0.1:8200"}

В Vault по пути airflow/connections/my_prod_db кладёте JSON:

{"conn_type": "postgres", "host": "localhost", "login": "user", "password": "pass", "port": 5432}

Airflow будет запрашивать секрет при каждом обращении к hook. Плюсы: централизованное управление, аудит, ротация паролей без остановки Airflow.

Типичные грабли

  1. Путаница с приоритетами. Airflow ищет connection в порядке: Secrets Backend -> Переменные окружения AIRFLOW_CONN_* -> База данных Airflow. Убедитесь, что в базе не осталось старых подключений, перекрывающих ваши env-переменные.
  2. Экранирование спецсимволов в URI. Если в пароле есть @, #, %, их нужно percent-encode. Для p@ss%word строка будет postgres://user:p%40ss%25word@host/db.
  3. Лишние права. Для работы с внешними Secrets Backend (например, Vault) инстанс Airflow должен иметь права на чтение секретов. Настройте политики доступа аккуратно, по принципу наименьших привилегий.
  4. Кэширование. Некоторые Secrets Backend кэшируют значения для производительности. Учитывайте это при смене паролей.

Выбор метода зависит от вашего стека: для локального развития хватит UI, в продакшене на Kubernetes используйте связку AIRFLOW_CONN_* + Kubernetes Secrets, а в зрелой инфраструктуре — внешний Secrets Backend. Главное — ни один пароль не должен оказаться в вашем репозитории с DAG.