How to include my own env var in email subject template?

I’m trying to customize the alert email subject so that it contains one of my env vars (such as production, integration, staging, etc.). I have this in airflow.cfg

[email]
email_backend = airflow.utils.email.send_email_smtp
subject_template = /path/to/subject_template_file

and in my subject_template_file i have

Production Airflow alert: {{ti}}

Is there a way to automatically set the word “Production” based on one of my env vars?
I have an env var called ENV which represent the environment i’m using. I wish it would be as simple as

{{os.getenv("ENV")}} Airflow alert: {{ti}}

but jinja2 doesn’t allow that or similar customized python calls in its {{}} without changing airflow source code

You can create user defined macros, which you can then reference in your jinja templates described in the Airflow documentation.

Here is an example.

import os
from datetime import datetime

from airflow.models import DAG
from airflow.operators.python_operator import PythonOperator


def print_args(arg):
    print(arg)


dag = DAG(
    dag_id='my_dag',
    schedule_interval='@once',
    user_defined_macros={
        'ENV': os.environ['ENV']
    },
    start_date=datetime(2020, 1, 1)
)

a = PythonOperator(
    task_id='a',
    python_callable=print_args,
    op_kwargs={
        'arg': '{{ ENV }}'
    },
    dag=dag
)

i suppose this new macro ENV defined in your example is only available in this DAG since the comment says "allows you to ``{{ foo }}`` in all jinja templates related to this DAG"
but i want it available to all other DAGs :thinking:

what i am doing now is adding this to the entrypoint.sh:

if [ "${ENV,,}" == "production" ]; then
  export AIRFLOW__EMAIL__SUBJECT_TEMPLATE="/usr/local/airflow/production_email_subject_template.j2"
fi
if [ "${ENV,,}" == "integration" ]; then
  export AIRFLOW__EMAIL__SUBJECT_TEMPLATE="/usr/local/airflow/integration_email_subject_template.j2"
fi

Well if you want it available to all your DAGs then you can simply make it into an Airflow Variable defined as an Environment Variable.

You can then render that Airflow Variable with Macros.

The var template variable allows you to access variables defined in Airflow’s UI. You can access them as either plain-text or JSON. If you use JSON, you are also able to walk nested structures, such as dictionaries like: {{ var.json.my_dict_var.key1 }} .

It is also possible to fetch a variable by string if needed with {{ var.value.get('my.var', 'fallback') }} or {{ var.json.get('my.dict.var', {'key1': 'val1'}) }} . Defaults can be supplied in case the variable does not exist.

ah very interesting, so i’ll just add this in my entrypoint.sh:

export AIRFLOW_VAR_ENV=$ENV

and do this in my email_subject_template.j2:

{{ var.value.env }} Airflow alert: {{ ti }}

correct?

Yep, I think that should work!