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.
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.
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.
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
:
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)
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:
module.exports = {
value_or_undefined: process.env.MY_ENV_VAR,
value_or_default: process.env.MY_OTHER_ENV_VAR || 'my_default_value'
}
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`
}
}
})