Guides
Code reusability
Referencing environment variables

Referencing environment variables

Use case

We want to move important or frequently changing configuration values (e.g., passwords and other secrets) to environment variables and then reference them in the data model code and configuration files.

It would prevent these values from being stored in a source code repository and being exposed to more people than needed. It would also allow to update the deployment configuration without changing the source code.

Configuration

In Cube Core, you can put environment variables into docker-compose.yml. In Cube Cloud, you can manage environment variables via the Settings page of your deployment.

cube.py file

In the cube.py configuration file, you can access environment variables either via the getenv function or the environ dictionary from the os package. getenv returns None if the variable is not set and allows to provide a default value. environ raises a KeyError if the variable is not set.

cube.py
import os
 
value_or_none = os.getenv('MY_ENV_VAR')
print(value_or_none)
 
value_or_default = os.getenv('MY_OTHER_ENV_VAR', 'my_default_value')
print(value_or_default)
 
value_or_error = os.environ['MY_OTHER_ENV_VAR']
print(value_or_error)

cube.js file

In the cube.js configuration file, you can access environment variables via the global process.env object. It returns undefined if the variable is not set. You can use the || operator to provide a default value.

cube.js
value_or_undefined = process.env.MY_ENV_VAR
console.log(value_or_undefined)
 
value_or_default = process.env.MY_OTHER_ENV_VAR || 'my_default_value'
console.log(value_or_default)

Data modeling

YAML files

In YAML data model files, you can access environment variables via the built-in env_var Jinja function. It raises an error if the variable is not set and allows to provide a default value.

model/cubes/my_cube.yml
cubes:
  - name: my_cube
    description: "{{ env_var('MY_ENV_VAR') | safe }}"
    sql_table: "{{ env_var('MY_OTHER_ENV_VAR', 'my_default_value') | safe }}.table"
 
    measures:
      - name: count
        type: count

globals.py file

In the globals.py file, similarly to the cube.py file, you can access environment variables either via the getenv function or the environ dictionary from the os package.

Consider the following file structure:

.
└── model
    └── globals.py
    └── cubes
        └── my_cube.yml

You can access environment variables in the globals.py file and potentially expose them to Jinja templates via TemplateContext:

model/globals.py
from cube import TemplateContext
import os
 
template = TemplateContext()
 
value_or_none = os.getenv('MY_ENV_VAR')
template.add_variable('value_or_none', value_or_none)
 
value_or_default = os.getenv('MY_OTHER_ENV_VAR', 'my_default_value')
template.add_variable('value_or_default', value_or_default)
model/cubes/my_cube.yml
cubes:
  - name: my_cube
    description: "{{ value_or_none | safe }}"
    sql_table: "{{ value_or_default | safe }}.table"
 
    measures:
      - name: count
        type: count

JavaScript files

In JavaScript data model files, the global process.env object is not available. However, you can use that object in JavaScript files outside of the data model directory and import from those files.

Consider the following file structure:

.
├── env.js
└── model
    └── cubes
        └── my_cube.js

You can't access process.env in the my_cube.js file but you can do that in the env.js file since it's outside of the model directory:

env.js
module.exports = {
  value_or_undefined: process.env.MY_ENV_VAR,
  value_or_default: process.env.MY_OTHER_ENV_VAR || 'my_default_value'
}
model/cubes/my_cube.js
import { value_or_undefined, value_or_default } from '../env'
 
cube(`my_cube`, {
  description: `${value_or_undefined}`,
  sql_table: `${value_or_default}.table`,
  
  measures: {
    count: {
      type: `count`
    }
  }
})