Skip to content

Environment Variables

Environment variables allow you to provide values to your application that may vary from environment to environment. Most likely you will run your application in more than one environment (e.g. dev, staging, prod). Even though they run the same code, they will need different configuration values and credentials. By using environment variables you can provide these values to your application without hard-coding them in your source code. This greatly enhances your application's security. Separating your application's configuration from its source code is a key tenet of a 12-factor app.

All the environment variables for an application can be viewed on the Env Variables tab. Use this table to ensure that you are utilizing the correct env variable names in your code. Unless the value is a secret, you can also see the value for the env variable.

Environment Variables

The sections below will describe the environment variables that Nullstone provides by default and how to add your own.

Injected By Nullstone

By default, Nullstone automatically injects a set environment variables into your application that describe its setup.

Nullstone Environment Variables

These environment variables are added for your convenience and can be valuable for a number of different scenarios.

One of the primary use cases is to include these values in your logging to make it easier to track down bugs. If the NULLSTONE_VERSION or NULLSTONE_COMMIT_SHA is logged, it makes tracking down the introduction of a bug much easier. If an error is only logged with a specific version or commit sha, you know the version or commit that introduced the bug. Once you roll out a fix, you can filter logs to the specific version or commit to determine if the error is still happening.

When you are logging for an application, it is very helpful to segment your logs by environment. Be sure to include the NULLSTONE_ENV environment variable in your logs messages or as part of the log metadata for structured logs. Keeping your dev logs and prod logs separate makes it much easier to find the logs you are looking for.

Setting up CORS protection for your application requires that you specific a set of known hosts that are allowed to access your application. The NULLSTONE_PUBLIC_HOSTS environment variable provides a comma delimited list of values to use as configuration. The values in this environment variable are specific to each environment so using this provides a one-step CORS configuration for all of your environments.

From Capabilities

Another way that environment variables get automatically added to your applications is through the capabilities that you add to your application. Each capability can have 0 to many environment variables that it automatically injects.

One of the primary use cases for this are database access capabilities. In addition to setting up database access, the credentials need to access the database are also injected as environment variables. Because these credentials are sensitive, they are marked as secrets and never leave your cloud account. This eliminates the need to handle or copy any database credentials; providing a more secure mechanism for accessing your database.

As you add capabilities to your application, the environment variables it adds are displayed in the dialog. The environment variables added are also displayed in the table on the Env Variables tab. Capability Environment Variables

Custom Environment Variables

In addition to the Nullstone and Capability environment variables, you can also add your own environment variables. To add one environment variable at a time, click the Add Variable button on the Env Variables tab.

Add Environment Variable

To add multiple environment variables at once, click the Add Multiple button on the Env Variables tab. When adding multiple environment variables, you can paste a list of key/value pairs in the same format as a .env file. Add Multiple Environment VariablesAdd Multiple Environment Variables Confirm

After adding your environment variables, they will show up as pending changes. Pending Environment Variables Click on Update to apply your changes and deploy your application with the new environment variables.

Interpolation

It is often useful to have the value of one environment variable be based on the value of one or more other environment variables. Nullstone provides this functionality by allowing you to use handlebar syntax to interpolate values from other environment variables. You can use as many environment variables as you like in the template for your new environment variable.

javascript
// Interpolation
NULLSTONE_STACK = "primary"
NULLSTONE_APP = "acme-api"
NULLSTONE_ENV = "dev"
MY_NEW_VAR = "{{ NULLSTONE_STACK }}.{{ NULLSTONE_APP }}.{{ NULLSTONE_ENV }}"
// MY_NEW_VAR = "primary.acme-api.dev"
// Interpolation
NULLSTONE_STACK = "primary"
NULLSTONE_APP = "acme-api"
NULLSTONE_ENV = "dev"
MY_NEW_VAR = "{{ NULLSTONE_STACK }}.{{ NULLSTONE_APP }}.{{ NULLSTONE_ENV }}"
// MY_NEW_VAR = "primary.acme-api.dev"

Or, you might just want to rename an environment variable so that you don't have to change your code.

javascript
// Renaming
DATABASE_URL = "{{ POSTGRES_URL }}"
// Renaming
DATABASE_URL = "{{ POSTGRES_URL }}"

Reference Existing Secrets

In addition to referencing other environment variables, you can also reference existing secrets from your secrets vault. To reference a secret in interpolation, you must provide the arn as the identifier of the secret. Wrap the arn with secret() to indicate that you are referencing a secret.

javascript
DATABASE_URL = "{{ secret(arn:aws:secretsmanager:us-east-1:0123456789012:secret:my_little_secret) }}"
DATABASE_URL = "{{ secret(arn:aws:secretsmanager:us-east-1:0123456789012:secret:my_little_secret) }}"

In the example above, the value of DATABASE_URL will be set to the value of the secret. The value will be retrieved from the secrets vault at runtime and injected into your application. The secret value will never be returned or displayed by Nullstone.

TIP

When referencing secrets in interpolation, you can only provide a reference to a single secret. The value can not be concatenated with other values. To concatenate values, first create an environment variable that references the secret. Then create a second environment variable to concatenate the values.

TIP

When referencing secrets in interpolation, the environment variable can NOT be marked as sensitive. The resulting value is sensitive, but the environment variable itself is not.

Secrets

For any environment variable you add, you have the option to mark it as a secret. Doing so will make sure that the value is saved securely in a secrets vault in your cloud account and never leaves your cloud. When marked as a secret, the value will be shown as •••••••••• in the UI and will never be returned from any APIs. The only way to access the values are through cloud account access.

Container Applications

For container applications, the values will be injected into the container as environment variables. You can access the values in your code using the standard environment variable syntax for your programming language.

javascript
// Javascript
process.env.KEY;
// Javascript
process.env.KEY;
python
# Python
import os
os.environ.get('KEY')
# Python
import os
os.environ.get('KEY')
elixir
# Elixir
System.get_env("KEY")
# Elixir
System.get_env("KEY")

Serverless Applications

For serverless applications, the secret keys will be injected into the container and the values must be retrieved from the secrets vault using code. First retrieve the secret key from the environment variable and then use the key to retrieve the value from the secrets vault.

javascript
// A javascript example
// Use the AWS SDK to retrieve the secret value from AWS Secrets Manager
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager"; // ES Modules import

const config = {
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
};
const secretId = process.env.SECRET_KEY;

const client = new SecretsManagerClient(config);
const command = new GetSecretValueCommand(secretId);
const response = await client.send(command);
// A javascript example
// Use the AWS SDK to retrieve the secret value from AWS Secrets Manager
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager"; // ES Modules import

const config = {
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
};
const secretId = process.env.SECRET_KEY;

const client = new SecretsManagerClient(config);
const command = new GetSecretValueCommand(secretId);
const response = await client.send(command);

Static Sites

Static sites can not use secret environment variables. All the code and configuration for a static site is delivered to the browser so there is no way to keep these values secret.

Build-Time Environment Variables

Nullstone recommends building your applications as portable containers. This means that the same container image can be deployed to any environment. The environment variables will then be injected into the container at runtime.

However, there may be scenarios where you would like to build a different container image for each environment. In this scenario, you can use build-time environment variables to customize your build process. To support this, Nullstone also injects environment variables into the build process for your applications.

Any custom or Nullstone injected environment variables will be injected into the build process. Capability environment variables are not yet supported for build-time. These include:

  • NULLSTONE_STACK
  • NULLSTONE_APP
  • NULLSTONE_ENV
  • NULLSTONE_VERSION
  • NULLSTONE_COMMIT_SHA
  • any custom environment variables you have added

Environment variable interpolation is also supported for build-time environment variables. So if you have an environment variable such as:

MY_CUSTOM_ENV_VAR = "{{ NULLSTONE_APP }}-{{ NULLSTONE_ENV }}"
MY_CUSTOM_ENV_VAR = "{{ NULLSTONE_APP }}-{{ NULLSTONE_ENV }}"

This value will be calculated before being injected. If NULLSTONE_APP = acme-api and NULLSTONE_ENV = dev, then the value injected for MY_CUSTOM_ENV_VAR will be acme-api-dev.

TIP

  • For container applications, the build-time environment variables are provided as build args when building the docker image.
  • For static site builds, the build-time environment variables are provided as environment variables to the build process.