how to migrate Airflow variables between environments
Shows how to move Airflow Variables between environments with export and import. Use when promoting DAGs from dev to staging to prod, when rebuilding an environment, or when keeping variables in version control. Not for moving connections, for secrets (use a secrets backend), or for values that differ per environment without a plan for overrides.
TL;DR
Variables live in each environment's metadata DB, so they dont follow your DAG code. Export them with airflow variables export, review the file for secrets and per-environment values, then airflow variables import in the target. For values that must never drift, define them as AIRFLOW_VAR_ environment variables in your deployment config instead.
how to migrate Airflow variables between environmentsUse this when
- Promoting DAGs from dev to staging to production
- Rebuilding an environment from scratch
- You want variables reviewed in version control like code
Not for this skill when
- Moving connections (separate command, separate skill)
- The value is a secret (belongs in a secrets backend, not a Variable)
- Values legitimately differ per environment and you have no override strategy yet
Steps
- Export the variables from the source environment:
airflow variables export vars.jsonExpected output: a JSON file with every variable key and value. This is your migration artifact; treat it like a database dump.
- Review the file before it goes anywhere. Redact secrets and flag per-environment values:
python -c "import json; d=json.load(open('vars.json')); print(sorted(d.keys()))"Expected output: the key list. Any key holding a credential gets deleted from the file and moved to a secrets backend; any key with a host or bucket name gets marked for per-environment override.
- Import into the target environment:
airflow variables import vars.jsonExpected output: the variables appear in the target. Import overwrites existing keys silently, so back up the target's variables first if they matter.
- Handle per-environment differences with a small override file or env vars rather than hand-editing after import:
export AIRFLOW_VAR_WAREHOUSE_SCHEMA=analytics_prodExpected output: the env var takes precedence over the imported value for that key. Keep the override list in your deployment config so it is reproducible.
- Verify the values landed correctly in the target:
airflow variables get my_keyExpected output: the expected value. Spot-check the keys your DAGs actually read; a bulk import that silently mangled one JSON blob will only show up here.
Variant phrasings
airflow variables export import json
The two-command flow above. Export writes JSON, import reads it; the format is stable across versions, so this works as a backup format too.
sync airflow variables dev to prod
Export from dev, review, import to prod, then apply prod overrides. Never import prod variables into dev if they contain anything sensitive; the flow should be one-directional for secrets.
airflow variables as code
For teams that want full reproducibility, skip the DB entirely for non-secret config: set AIRFLOW_VAR_[KEY] in the deployment manifests. The DB then holds only what operators set by hand, and rebuilds are trivial.
Why it happens
Variables are runtime configuration stored in the metadata database, and each environment has its own database by design. Code deploys dont touch the DB, so variables never travel with a deploy. That separation is intentional (config differs per environment), but it means migration is a deliberate step, not an automatic one.
Edge cases
- JSON-valued variables deserialize on read: a value that looks like a number or boolean comes back as that type, which surprises code expecting strings. Quote deliberately.
- Import overwrites without warning; export the target's variables first if you might need to roll back.
- Variables have no built-in per-environment layering, so the override strategy (step 4) is on you. Document which keys differ per environment.
- Large variable values (kilobytes) work but slow the UI; big blobs belong in object storage with the key in the variable.
- The export includes everything, so in a shared Airflow instance filter the file down to your team's keys before importing elsewhere.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_CHHMCvgTR6XUEP4nHPIv3g