dbt Environment Variables
Environment variables let you pass sensitive or environment-specific values into dbt without hardcoding them in files. Credentials, schema names, feature flags, and API keys all belong in environment variables rather than in code that gets committed to version control.
Reading Environment Variables in dbt
Use the env_var() Jinja function anywhere in dbt that accepts Jinja: profiles.yml, dbt_project.yml, model SQL files, macros, and schema.yml.
# Syntax
{{ env_var('VARIABLE_NAME') }}
# With a default value (used when the variable is not set)
{{ env_var('VARIABLE_NAME', 'default_value') }}Using env_var() in profiles.yml
The most critical use of environment variables is keeping secrets out of profiles.yml:
# profiles.yml
my_project:
target: "{{ env_var('DBT_TARGET', 'dev') }}"
outputs:
dev:
type: snowflake
account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"
user: "{{ env_var('SNOWFLAKE_USER') }}"
password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
role: "{{ env_var('SNOWFLAKE_ROLE', 'TRANSFORMER') }}"
database: ANALYTICS
warehouse: COMPUTE_WH
schema: "{{ env_var('DBT_SCHEMA', 'dbt_dev') }}"
threads: 4
prod:
type: snowflake
account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"
user: "{{ env_var('SNOWFLAKE_PROD_USER') }}"
password: "{{ env_var('SNOWFLAKE_PROD_PASSWORD') }}"
schema: DBT_PROD
threads: 8Setting Environment Variables in the Shell
# macOS / Linux export SNOWFLAKE_ACCOUNT=abc12345.us-east-1 export SNOWFLAKE_USER=alice export SNOWFLAKE_PASSWORD=my_secret_password export DBT_SCHEMA=dbt_alice_dev # Windows (Command Prompt) set SNOWFLAKE_ACCOUNT=abc12345.us-east-1 set SNOWFLAKE_PASSWORD=my_secret_password # Windows (PowerShell) $env:SNOWFLAKE_ACCOUNT = "abc12345.us-east-1" $env:SNOWFLAKE_PASSWORD = "my_secret_password"
Using env_var() in dbt_project.yml
# dbt_project.yml
vars:
target_schema: "{{ env_var('DBT_SCHEMA', 'dbt_dev') }}"
enable_new_feature: "{{ env_var('ENABLE_NEW_FEATURE', 'false') }}"Using env_var() in Models
-- models/fct_orders.sql
{% set schema = env_var('DBT_SCHEMA', 'analytics') %}
select
order_id,
customer_id,
amount_dollars
from {{ ref('stg_orders') }}
where schema_name = '{{ schema }}'Environment Variables in CI/CD
CI/CD systems (GitHub Actions, GitLab CI, Bitbucket Pipelines) let you store secrets as encrypted environment variables and inject them into pipeline runs:
# GitHub Actions example
name: dbt CI Run
on: [pull_request]
jobs:
dbt-build:
runs-on: ubuntu-latest
env:
SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
DBT_SCHEMA: dbt_ci_${{ github.run_id }}
steps:
- uses: actions/checkout@v3
- run: pip install dbt-snowflake
- run: dbt deps
- run: dbt build --target ciPer-Developer Schemas Using env_var()
Each developer can work in their own schema without conflicts by setting a personal environment variable:
# profiles.yml
my_project:
target: dev
outputs:
dev:
type: postgres
schema: "dbt_{{ env_var('DBT_USER', 'shared') }}"# Developer Alice's shell export DBT_USER=alice dbt run # writes to dbt_alice schema # Developer Bob's shell export DBT_USER=bob dbt run # writes to dbt_bob schema
Feature Flags with env_var()
-- models/fct_orders.sql
select
order_id,
{% if env_var('ENABLE_MARGIN_CALC', 'false') == 'true' %}
amount_dollars - cost_dollars as gross_margin,
{% endif %}
amount_dollars
from {{ ref('stg_orders') }}# Enable the new column in production export ENABLE_MARGIN_CALC=true dbt run
dbt Cloud Environment Variables
In dbt Cloud, set environment variables in the project settings under "Environment Variables." They are scoped per environment (dev/prod) and encrypted at rest. You do not need to set them in a shell — dbt Cloud injects them automatically before each run.
Security Rules
- Never commit actual secrets (passwords, API keys) to your Git repository
- Use
env_var()with no default for required secrets — dbt fails fast if they are missing - Use
env_var()with a default for optional settings that have safe fallbacks - Add
.envfiles to.gitignoreif you use them for local development
