Environment variables, which are key-value pairs configured outside your source code, allow you to dynamically modify application behavior depending on environment.
Using environment variables, you can define various configuration options for your Dagster application and securely set up secrets. For example, instead of hard-coding database credentials - which is bad practice and cumbersome for development - you can use environment variables to supply user details. This allows you to parameterize your pipeline without modifying code or insecurely storing sensitive data.
How environment variables are declared depends on whether you're developing locally or have already deployed your Dagster project.
As of Dagster 1.1.0, Using .env files is supported for loading environment variables into local environments. A .env file is a text file containing key-value pairs that is used locally, but not checked into source control. Using a .env file allows you to develop and test locally without putting sensitive info at risk. For example:
If Dagster detects a .env file in the same folder where dagster-webserver or dagster-daemon is launched, it will automatically load the environment variables in the file. This also applies to variables exported from Dagster Cloud.
When using a .env file, keep the following in mind:
The .env file must be in the same folder where dagster-webserver or dagster-daemon is launched
Any time the .env file is modified, the workspace must be re-loaded to make the Dagster webserver/UI aware of the changes
Environment variables can be set a variety of ways in Dagster Cloud:
How environment variables are set for Dagster projects deployed on your infrastructure depends on where Dagster is deployed. Refer to the deployment guide for your platform for more info:
Configurable Dagster objects - such as ops, assets, resources, I/O managers, and so on - can accept configuration from environment variables. Dagster provides a native way to specify environment variables in your configuration. These environment variables are retrieved at launch time, rather than on initialization as with os.getenv.
This approach has a few unique benefits:
It provides greater observability. You can see which configuration values are sourced from environment variables in the UI.
It ensures secret values are hidden in the launchpad, resources UI, and other places where configuration is displayed.
It makes testing easier, since you can provide string values directly to configuration rather than environment variables.
Using environment variables to provide secrets ensures sensitive info won't be visible in your code or the launchpad in the UI. In Dagster, best practice for handling secrets uses configuration and resources.
A resource is typically used to connect to an external service or system, such as a database. Resources can be configured separately from the rest of your app, allowing you to define it once and reuse it as needed.
Let's take a look at an example from the Dagster Crash Course, which creates a GitHub resource and supplies it to assets. Let's start by looking at the resource:
This code creates a GitHub resource named GithubClientResource
By subclassing ConfigurableResource and specifying the access_token field, we're telling Dagster that we want to be able to configure the resource with an access_token parameter
Since access_token is a string value, this config parameter can either be:
An environment variable, or
Provided directly in the configuration
As storing secrets in configuration is bad practice, we'll opt for using an environment variable. In this code, we're configuring the resource supplying it to our assets:
We pass configuration info to the resource when we construct it. In this example, we're telling Dagster to load the access_token from the GITHUB_ACCESS_TOKEN environment variable by wrapping it in EnvVar.
We're adding that resource to our Definitions object so it's available for our assets.
In this example, we'll demonstrate how to use different I/O manager configurations for local and production environments using configuration (specifically the configured API) and resources.
We've created a dictionary of resource definitions, resources, named after our local and production environments. In this example, we're using a Pandas Snowflake I/O manager.
For both local and production, we constructed the I/O manager using environment-specific run configuration. Note the differences in configuration between local and production, specifically where environment variables were used.
Following the resources dictionary, we define the deployment_name variable, which determines the current executing environment. This variable defaults to local, ensuring that DAGSTER_DEPLOYMENT=PRODUCTION must be set to use the production configuration.
Let's look at a function that determines the current deployment using the DAGSTER_CLOUD_IS_BRANCH_DEPLOYMENT environment variable:
defget_current_env():
is_branch_depl = os.getenv("DAGSTER_CLOUD_IS_BRANCH_DEPLOYMENT")=="1"assert is_branch_depl !=None# env var must be setreturn"branch"if is_branch_depl else"prod"
This function checks the value of DAGSTER_CLOUD_IS_BRANCH_DEPLOYMENT and, if equal to 1, returns a variable with the value of branch. This indicates that the current deployment is a Branch Deployment. Otherwise, the deployment is a full deployment and is_branch_depl will be returned with a value of prod.
Using this info, we can write code that executes differently when in a Branch Deployment or a full deployment.
You have attempted to fetch the environment variable "[variable]" which is not set. In order for this execution to succeed it must be set in this environment.
Surfacing when a run is launched in the UI, this error means that an environment variable set using StringSource could not be found in the executing environment.
Verify that the environment variable is named correctly and accessible in the environment.
If developing locally and using a .env file, try re-loading the workspace in the UI. The workspace must be re-loaded any time this file is modified for the UI to be aware of the changes.