Data Engineering  /  Airflow

๐ŸŒฌ๏ธ Apache Airflow Guide 4 of 4 18 guides ยท updated 2026

Workflow orchestration with Airflow โ€” DAGs, operators, scheduling, executors, and the production practices that keep pipelines reliable.

Airflow Providers & Connections

Core Airflow ships with the scheduler, executor framework, and a handful of generic operators โ€” but almost nothing that talks to a specific external system. Thatโ€™s the job of providers: separately-versioned packages, installed independently of Airflow itself, that add operators, hooks, and sensors for a given piece of infrastructure.


What a Provider Package Contains

Terminal window
pip install apache-airflow-providers-amazon
pip install apache-airflow-providers-snowflake
pip install apache-airflow-providers-google

Each provider bundles three kinds of components: operators (task templates for that system โ€” S3ToRedshiftOperator, SnowflakeOperator, BigQueryInsertJobOperator), hooks (lower-level clients used internally by operators, and directly usable in PythonOperator/@task callables when you need more control than an operator provides), and sensors (waiting on conditions specific to that system, like S3KeySensor).

from airflow.providers.snowflake.operators.snowflake import SnowflakeOperator
run_query = SnowflakeOperator(
task_id="run_transform",
snowflake_conn_id="snowflake_default",
sql="CALL transform_orders();",
)

There are well over 80 official providers today, covering essentially every major cloud platform, database, and SaaS tool a data pipeline is likely to touch โ€” this breadth is one of Airflowโ€™s biggest practical advantages over newer orchestrators with smaller ecosystems.


Connections: Centralized Credential Management

A Connection is Airflowโ€™s abstraction for โ€œhow to reach an external systemโ€ โ€” host, port, credentials, and extra configuration, stored once (encrypted, via Airflowโ€™s Fernet key or an external secrets backend) and referenced by ID from any task that needs it, rather than hardcoded into DAG code.

# The task references a connection by ID โ€” no credentials in the DAG file itself
run_query = SnowflakeOperator(
task_id="run_transform",
snowflake_conn_id="snowflake_default", # looked up at runtime
sql="CALL transform_orders();",
)

Connections are managed through the UI (Admin โ†’ Connections), the CLI (airflow connections add), environment variables, or โ€” for production โ€” an external secrets backend (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager) configured via secrets.backend in airflow.cfg, so credentials never live in Airflowโ€™s own metadata database at all.

Terminal window
airflow connections add 'snowflake_default' \
--conn-type 'snowflake' \
--conn-login 'svc_airflow' \
--conn-password '<use a secrets backend, not this flag, in real deployments>' \
--conn-extra '{"account": "xy12345", "warehouse": "ETL_WH"}'

Hooks: The Layer Underneath Operators

A hook is the lower-level client an operator uses internally โ€” and itโ€™s directly usable yourself for cases an existing operator doesnโ€™t cover:

from airflow.providers.snowflake.hooks.snowflake import SnowflakeHook
from airflow.decorators import task
@task
def custom_snowflake_logic():
hook = SnowflakeHook(snowflake_conn_id="snowflake_default")
records = hook.get_records("SELECT count(*) FROM orders")
return records[0][0]

Reaching for the hook directly inside a @task/PythonOperator callable is the standard escape hatch whenever the pre-built operator for a system doesnโ€™t quite do what a specific task needs โ€” you get the connection management for free without needing a bespoke operator to exist for your exact use case.


Common Mistakes

Hardcoding credentials directly in DAG files instead of using Connections โ€” this puts secrets in source control (DAG files are typically version-controlled) and bypasses Airflowโ€™s credential-masking in logs and UI.

Installing every provider โ€œjust in case.โ€ Each provider adds dependencies and potential version-conflict surface area โ€” install only what your actual DAGs use, and pin provider versions deliberately rather than letting them float.

Not using an external secrets backend in production, relying instead on Airflowโ€™s built-in Connections UI/database storage โ€” workable for smaller deployments, but a real secrets manager (Vault, AWS Secrets Manager) is the standard for anything handling production credentials at scale.

Frequently Asked Questions

Are providers versioned separately from Airflow core? Yes โ€” this is deliberate, letting a provider ship bug fixes or new operators without requiring an Airflow core upgrade, and letting different providers evolve at their own pace.

Can a DAG use multiple providers together? Yes, routinely โ€” a single pipeline might use the Amazon provider to read from S3, the Snowflake provider to load data, and the Slack provider to send a completion notification, all within the same DAG.

What if no provider exists for a system I need to integrate with? Write a custom hook/operator using BaseHook/BaseOperator as a starting point, or fall back to PythonOperator calling whatever SDK/API client the system already provides โ€” providers are a convenience layer, not a hard requirement for integration.

Summary

Providers are what turn Airflow from a generic task scheduler into something that can actually talk to AWS, Snowflake, Kubernetes, Slack, and hundreds of other systems out of the box, and Connections centralize the credentials those integrations need so they never end up hardcoded in DAG source. Together theyโ€™re a large part of why Airflowโ€™s ecosystem breadth remains one of its strongest practical advantages over newer orchestration tools.