Variable Groups
Environment variable groups are similar to regular Environment Variables and support the same features like being secretable and interpolated in other parts of the YAML Configuration, with two key differences:
- They are not auto injected to containers, you decide which group should be applied to what component
- They do no inherit from Project Variables
Compatibility
The regular Environment Variables defined on the environment or project will work alongside groups.
Using groups allows fine grained control on which components have access to each specific group.
Example
To create a new group simply add it to the YAML under environmentVariablesGroups
:
kind: Environment
type: primary
name: Var Group Example
environmentVariablesGroups:
rabbitmq:
RABBITMQ_DEFAULT_USER: example
RABBITMQ_DEFAULT_PASS: SECRET[password]
RABBITMQ_NODE_PORT: 5672
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: |
-ra wal_max_size_bytes 32000000
-rabbit vm_memory_high_watermark {absolute,420000000}
queue:
QUEUE_HOST: localrabbitmq
QUEUE_DOMAIN: '{{ env.varGroups.queue.QUEUE_HOST }}:{{ env.varGroups.rabbitmq.RABBITMQ_NODE_PORT }}'
QUEUE_AUTH: '{{ env.varGroups.rabbitmq.RABBITMQ_DEFAULT_USER }}:{{ env.varGroups.rabbitmq.RABBITMQ_DEFAULT_PASS }}'
QUEUE_DSN: 'amqp://{{ env.varGroups.queue.QUEUE_AUTH }}@{{ env.varGroups.queue.QUEUE_DOMAIN }}/'
data:
just: some
data: here
components:
-
kind: Application
name: rabbitmq
dockerCompose:
image: 'rabbitmq:latest'
ports:
# no interpolation support in ports
- '5672:5672'
environmentVariablesGroups:
- rabbitmq
hostname: '{{ env.varGroups.queue.QUEUE_HOST }}'
-
kind: Application
name: backend
dockerCompose:
image: 'nginx:latest'
environmentVariablesGroups:
- queue
-
kind: Application
name: worker
dockerCompose:
image: 'python:latest'
environmentVariablesGroups:
- rabbitmq
- queue
environment:
LOG_LEVEL: DEBUG
-
kind: SidecarContainer
name: monitor
dockerCompose:
image: docker:20.10.17-dind
command: 'tail -f /dev/null'
environmentVariablesGroups:
- queue
environment:
LOG_LEVEL: CRITICAL
-
kind: Application
name: frontend
dockerCompose:
image: 'nginx:latest'
pod:
sidecar_containers:
-
from: monitor
name: monitor-frontend
# as a sidecar, it will also inherit the group defined on the sidecar component
environmentVariablesGroups:
- rabbitmq
# as a sidecar, it will also inherit the environment from the main component
environment:
LOG_LEVEL: ERROR
In the above example we do the following:
- Set the
rabbitmq
group with the environment variables known to RabbitMQ - Set the
queue
group with ready a ready to use DSN - The rabbitmq service uses the
rabbitmq
group - The backend service uses the
queue
group because it can handle theQUEUE_DSN
- The worker service uses the both groups as an example
Injection precedence
When you are applying a group
to a Bunnyshell Component, it will override Project or Environment scoped variables.
When using multiple groups
the order in which they are defined within the component is the same order they will override any duplicate variables.
In the above example, the worker service uses both rabbitmq
and queue
groups, meaning any common variables defined in both groups will be overridden by queue
.
Kubernetes Resources
Upon deploying the above example, it will also generate a Kubernetes ConfigMap
for each group
in the environment namespace, with the name environ-{{ groupName }}
even when not directly used by components.
apiVersion: v1
data:
RABBITMQ_DEFAULT_USER: example
RABBITMQ_DEFAULT_PASS: password
RABBITMQ_NODE_PORT: '5672'
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-ra wal_max_size_bytes 32000000\n-rabbit vm_memory_high_watermark {absolute,420000000}\n"
kind: ConfigMap
metadata:
creationTimestamp: null
labels: { }
name: environ-rabbitmq
apiVersion: v1
data:
QUEUE_HOST: localrabbitmq
QUEUE_DOMAIN: localrabbitmq:5672
QUEUE_AUTH: example:password
QUEUE_DSN: 'amqp://example:password@localrabbitmq:5672/'
kind: ConfigMap
metadata:
creationTimestamp: null
labels: { }
name: environ-queue
apiVersion: v1
data:
just: some
data: here
kind: ConfigMap
metadata:
creationTimestamp: null
labels: { }
name: environ-data
Usage
You can additionally use a
ConfigMap
with Helm Components or Kubernetes Manifest Components
Advanced Usage
You can use the available filters and create custom encodings from your env var groups.
Dot Env File
{{ env.varGroups.queue | merge ({
APP_ENV: 'prod'
}) | kv_encode }}
When used against the above bunnyshell.yaml
configuration:
QUEUE_HOST=localrabbitmq
QUEUE_DOMAIN=localrabbitmq:5672
QUEUE_AUTH=example:password
QUEUE_DSN=amqp://example:password@localrabbitmq:5672/
APP_ENV=prod
Yaml Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ env.name|lower|slug }}-custom-config-map
data:
{{ env.varGroups.queue | merge ({
APP_ENV: prod
}) | yaml_encode({
inline: false,
indent: 4,
}) }}
When used against the above bunnyshell.yaml
configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: var-group-example-custom-config-map
data:
QUEUE_HOST: localrabbitmq
QUEUE_DOMAIN: localrabbitmq:5672
QUEUE_AUTH: example:password
QUEUE_DSN: 'amqp://example:password@localrabbitmq:5672/'
APP_ENV: prod
Updated 2 months ago