Principle:Apache Airflow Configuration Resolution
| Knowledge Sources | |
|---|---|
| Domains | Configuration, Core_Infrastructure |
| Last Updated | 2026-02-08 21:00 GMT |
Overview
Hierarchical configuration resolution from multiple sources with defined precedence, enabling configuration via files, environment variables, commands, and secrets backends with predictable override behavior.
Description
Airflow's configuration system resolves values from multiple sources with a strict priority ordering. When a configuration value is requested, the system checks each source in priority order and returns the first non-empty result. This design allows operators to:
- Set sensible defaults in the code itself
- Override defaults via the
airflow.cfgconfiguration file - Inject secrets from external backends (Vault, AWS SSM) without storing them in files
- Execute shell commands to dynamically compute values (e.g., fetching from metadata services)
- Use environment variables for container-based and CI/CD deployments, which override all file-based sources
This layered approach means a single Airflow installation can be configured differently across environments (development, staging, production) without modifying the configuration file, simply by adjusting environment variables or secrets backend entries.
Usage
This principle governs the resolution of every Airflow configuration value at runtime. It is relevant when:
- Setting up Airflow for the first time
- Moving between deployment environments
- Integrating with external secrets management systems
- Debugging unexpected configuration behavior
- Writing custom operators or plugins that read Airflow configuration
Theoretical Basis
Source Priority Ordering (Highest to Lowest):
| Priority | Source | Format | Example |
|---|---|---|---|
| 1 (highest) | Environment variables | AIRFLOW__{SECTION}__{KEY} (double underscores) |
AIRFLOW__CORE__EXECUTOR=LocalExecutor
|
| 2 | Command execution | {key}_cmd option in config file |
sql_alchemy_conn_cmd = /usr/bin/fetch_db_conn
|
| 3 | Secrets backend | Configured via [secrets] section |
HashiCorp Vault, AWS SSM, GCP Secret Manager |
| 4 | Configuration file | airflow.cfg (INI format) |
[core] section with executor = LocalExecutor
|
| 5 (lowest) | Built-in defaults | Hardcoded in Airflow source | Default values defined in configuration schema |
Environment Variable Convention:
Environment variables follow the pattern AIRFLOW__{SECTION}__{KEY} where double underscores separate the section and key. For example:
AIRFLOW__CORE__EXECUTORmaps to[core] executorAIRFLOW__DATABASE__SQL_ALCHEMY_CONNmaps to[database] sql_alchemy_connAIRFLOW__WEBSERVER__SECRET_KEYmaps to[webserver] secret_key
Type Coercion:
Raw configuration values are strings. The configuration parser applies type coercion based on the expected type of each option:
| Target Type | Coercion Rule | Example |
|---|---|---|
| bool | Case-insensitive: true/1/yes/on become True; false/0/no/off become False | "True" -> True
|
| int | Standard integer parsing | "8080" -> 8080
|
| float | Standard float parsing | "0.5" -> 0.5
|
| json | json.loads() for complex structures |
'{"key": "value"}' -> dict
|
| timedelta | Parses duration strings | "30s", "5m", "2h"
|
| enum | Matches against allowed enum values | "SequentialExecutor"
|
| import path | Imports the specified Python object | "my_module.MyClass" -> class object
|
Command Execution:
For options that support the _cmd suffix, Airflow executes the specified shell command and uses its stdout as the configuration value. This enables dynamic secret retrieval without a full secrets backend:
[database]
sql_alchemy_conn_cmd = /usr/local/bin/fetch_db_credentials.sh
The command is executed once at startup and the result is cached for the process lifetime.
Secrets Backend Integration:
When a secrets backend is configured, the configuration parser queries it for values before falling back to the config file. This is particularly useful for sensitive values like database credentials and API keys:
[secrets]
backend = airflow.providers.hashicorp.secrets.vault.VaultBackend
backend_kwargs = {"connections_path": "airflow/connections", "variables_path": "airflow/variables"}