Search
⌃K

Adding Environment Variables

This section shows how to add environment variables to existing services. The how-tos start from a fully working example, walk through changing it, and verifying that it works.
See Blueprints Concepts for an explanation on Velocity Blueprint annotations.

Add a constant environment variable

Because Velocity Blueprints are just annotated Kubernetes manifests, you can add an environment variable to a Blueprint just as you would add one to a K8s resource definition, like so:
spec:
containers:
- name: service-a
image: yeasy/simple-web:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env: # New env var
- name: EXAMPLE_ENV_VAR
value: example_value

Add an env var with the address of another Velocity Service

1. Start with your existing, working Velocity Blueprint

In this example, we'll use original-services.yaml.
We have two Velocity Services, service-a and service-b, that currently DO NOT depend on each other.
Note: To learn how to create a new Velocity Service, go to Adding Velocity Services
To view the existing dependencies between your Velocity Services, use the --dry-run flag as follows:
veloctl env create \
-f https://raw.githubusercontent.com/techvelocity/velocity-blueprints/main/examples/original-services.yaml --dry-run
The Depends On column should be empty, as shown below:
Requesting the creation of environment joyous-x-factor-investigations with services at 2022-09-19 17:51:00 IDT...
Velocity Resources
Kind Name Validation Depends On
Velocity Service service-a Valid
├─ Deployment service-a Valid
└─ Service service-a Valid
Velocity Service service-b Valid
├─ Deployment service-b Valid
└─ Service service-b Valid

2. Add an environment variable that references another service

In service-a, add a dependsOn annotation and an environment variable to the K8s Deployment definition that references service-b, like so:
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
velocity.tech.v1/id: service-a # Velocity service identifier
velocity.tech.v1/dependsOn: service-b
name: service-a
labels:
app: service-a
spec:
selector:
matchLabels:
app: service-a
replicas: 1
template:
metadata:
labels:
app: service-a
spec:
containers:
- name: service-a
image: yeasy/simple-web:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: SERVICE_B_URL
value: "http://{velocity.v1:service-b.exposures(port=http).host}:{velocity.v1:service-b.exposures(port=http).port}"
This adds a value that will resolve to service-b's Velocity Service configuration. For a detailed explanation of available Velocity Templates, see Global Properties.

3. Confirm that the env var is available in service-a

Run the following to deploy a Velocity Environment with that includes both service-a and service-b:
veloctl env create \
-f https://raw.githubusercontent.com/techvelocity/velocity-blueprints/main/examples/service-a-references-service-b.yaml
You should see the following in the Velocity UI:

Add an environment variable with a ConfigMap

1. Start with your existing, working Velocity Blueprint

In this example, we'll begin with original-services.yaml.
We have 2 services, service-a and service-b, which are configured as Velocity Services, and currently DO NOT depend on each other. (See Blueprints Concepts for an explanation of what it means for one Velocity Service to depend on another).

2. Add a dependency to service-b by using a configmap

Create the following K8s ConfigMap and associate it with service-a, like so:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: service-a
annotations:
velocity.tech.v1/dependsOn: service-b
data:
service-b_URL: "{velocity.v1:service-b.exposures(port=http).uri}"
service-b_HOST: "{velocity.v1:service-b.exposures(port=http).host}"
service-b_PORT: "{velocity.v1:service-b.exposures(port=http).port}"
And add the following to service-a's Deployment defintition:
env:
- name: service-b_URL
valueFrom:
configMapKeyRef:
name: service-a
key: service-b_URL
See the resulting Blueprint after these changes: referencing-service-b-via-configmap.yaml
Notice that the configmap is part of the service-a Velocity Service and that we identify the dependency of service-a on service-b.

Adding a K8s Secret as an environment variable

Use Case: You need to add a secret environment variable to an existing Velocity Service, where the secret is a dynamic value - for example: Each Velocity Environment has a different secret.
Refer to the Kubernetes Docs for more information about Kubernetes secrets.

1. Start with your existing, working Blueprint

In this example, we'll begin with original-service-a.yaml, a simple service with no environment variables.

2. Create a new K8s Secret or modify an existing one

---
apiVersion: v1
kind: Secret
metadata:
name: secret-env
type: Opaque
data:
DB_USERNAME: ZGItcGFzc3dvcmQte3ZlbG9jaXR5LnYxLmVudk5hbWV9 # base 64 encoding of "db-password-{velocity.v1.envName}"
Notice that the K8s Secret contains a Velocity Annotation. This will be resolved at provisioning time.

3. Change service-a environment variables to refer to a Kubernetes Secret

env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-env
key: DB_USERNAME
optional: false
See the resulting Blueprint after these changes: service-a-references-secret-with-annotations.yaml
Notice that the secrets are associated with service-a.
Also, for each developer, the encoded K8s Secret will be different since db-password-{velocity.v1.envName} resolves to a different value each time.

Adding AWS specific environment variables

Use Case1: Your application needs the AWS Region or AWS Account that your cluster is running on

If you need some of your environment variables to reference AWS cloud provider-specific variables, you have a number of predefined template variables that can be used:
- name: VELOCITY_TEST_AWS_ACCOUNT
value: "{velocity.v1.aws.accountID}"
- name: VELOCITY_TEST_AWS_REGION
value: "{velocity.v1.aws.region}"
See Global Properties for details on each template.

Use Case2: add an environment variable for an AWS SQS queue

Your application needs to reference an AWS SQS queue.

1. Start with your existing, working Blueprint

In this example, we'll use original-service-a.yaml, a simple service with no environment variables.

2. Create an AWS SQS queue

apiVersion: sqs.velocity.tech/v1
kind: Queue
metadata:
annotations:
velocity.tech.v1/id: queue # Velocity service identifier
velocity.tech.v1/exports-queue-name: path="metadata.name"
velocity.tech.v1/exports-queue-url: path="spec.queueUrl"
velocity.tech.v1/exports-queue-arn: path="spec.queueArn"
velocity.tech.v1/dependsOn: queue
name: "{velocity.v1.generate:cloudResourcePrefix(seed=queue)}-{velocity.v1.envName}-my-queue"
spec:
queueName: "{velocity.v1:queue.exports.queue-name}"
queueUrl: "https://sqs.{velocity.v1.aws.region}.amazonaws.com/{velocity.v1.aws.accountID}/{velocity.v1:queue.exports.queue-name}"
queueArn: "arn:aws:sqs:{velocity.v1.aws.region}:{velocity.v1.aws.accountID}:{velocity.v1:queue.exports.queue-name}"
The Template {velocity.v1.generate:cloudResourcePrefix(seed=queue)} creates a random name that complies with AWS naming conventions.
The Template {velocity.v1.envName} will be replaced at runtime with the developer's environment name.
See Global Properties for details on each template.
The resulting queueUrl and queueArn will be resolved at provisioning time to their correct values.

3. Change service-a environment variables to refer to the AWS SQS variables

apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
velocity.tech.v1/id: service-a # Velocity service identifier
velocity.tech.v1/dependsOn: queue
........
.......
env:
- name: QUEUE_NAME
value: "{velocity.v1:queue.exports.queue-name}"
- name: QUEUE_URL
value: "{velocity.v1:queue.exports.queue-url}"
See the resulting blueprint after these changes: aws-sqs.yaml
Verify that the Blueprint is defined without errors:
veloctl env create -f https://raw.githubusercontent.com/techvelocity/velocity-blueprints/main/examples/aws-sqs.yaml --dry-run
Requesting the creation of environment sad-firestar with services at 2022-09-20 23:15:28 IDT...
Velocity Resources
Kind Name Validation Depends On
Velocity Service queue Valid queue
└─ Queue.sqs.velocity.tech velocity-velo8ha2-2607qj09-sad-firestar-my-queue Valid queue
Velocity Service service-a Valid queue
├─ Deployment.apps service-a Valid queue
└─ Service service-a Valid
.......
.......
Velocity Service Property Resulted Value
service-a exposures(port=http).user
exposures(port=http).password
exposures(port=http).host service-a
exposures(port=http).port 80
exposures(port=http).scheme http
exposures(port=http).uri http://service-a:80
queue exports.queue-arn arn:aws:sqs:eu-central-1:228314819794:velocity-velo8ha2-2607qj09-sad-firestar-my-queue
exports.queue-name velocity-velo8ha2-2607qj09-sad-firestar-my-queue
exports.queue-url https://sqs.eu-central-1.amazonaws.com/228314819794/velocity-velo8ha2-2607qj09-sad-firestar-my-queue
Debug Information
- Set resource `{velocity.v1.generate:cloudResourcePrefix(seed=queue)}-{velocity.v1.envName}-my-queue` namespace to `sad-firestar`
- Attaching aws credentials to `Containerized/apps/v1/Deployment/service-a`
Success
Notice that the Velocity Service queue has correctly resolved the queue-url and queue-arn.
Refer to AWS SQS documentation for details on SQS naming.

Adding GCP specific environment variables

Use Case1: Your application needs the GCP Zone or GCP Project Id that your cluster is running on

If you need some of your environment variables to reference GCP cloud provider-specific variables, you have a predefined template variables that can be used:
env:
- name: VELOCITY_TEST_GCP_PROJECT
value: "{velocity.v1.gcp.projectName}"
- name: VELOCITY_TEST_GCP_ZONE
value: "{velocity.v1.gcp.zone}"
See Global Properties for details on each template.

Use Case2: Your application needs to either publish or subscribe to a GCP Pub/Sub Topic

1. Start with your existing working blueprint

In this example, we'll use original-service-a.yaml, a simple service with no environment variables.
To view the service, use the --dry-run flag as follows:
veloctl env create -f https://raw.githubusercontent.com/techvelocity/velocity-blueprints/main/examples/original-service-a.yaml --dry-run
Requesting the creation of environment crazy-flying-dutchman with services at 2022-09-20 18:10:52 IDT...
Velocity Resources
Kind Name Validation Depends On
Velocity Service service-a Valid
├─ Deployment.apps service-a Valid
└─ Service service-a Valid

2. Create a GCP Topic

apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubTopic
metadata:
annotations:
velocity.tech.v1/id: pubsub-topic # Velocity service identifier
velocity.tech.v1/exports-topic-name: path="metadata.name"
name: "{velocity.v1.generate:cloudResourcePrefix(seed=topic)}-{velocity.v1.envName}-topic"
The template {velocity.v1.generate:cloudResourcePrefix(seed=queue)} creates a random name that complies with GCP naming conventions.
The template {velocity.v1.envName} will be replaced at runtime with the developer's Velocity Environment name.
See Global Properties for details on each template.
See Config-Connector CRD sample for additional configuration options of pubsub-topic
The resulting metadata.name will be resolved at provisioning time to the correct value.

3. Create a GCP subscription

apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubSubscription
metadata:
annotations:
velocity.tech.v1/id: pubsub-subscription # Velocity service identifier
velocity.tech.v1/dependsOn: pubsub-topic, pubsub-subscription
velocity.tech.v1/exports-sub-name: path="metadata.name"
name: "{velocity.v1.generate:cloudResourcePrefix(seed=sub)}-{velocity.v1.envName}-sub"
spec:
topicRef:
name: "{velocity.v1:pubsub-topic.exports.topic-name}"

Change service-a environment variables to refer to the GCP topic and subscription variables

apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
velocity.tech.v1/id: service-a # Velocity service identifier
velocity.tech.v1/dependsOn: pubsub-topic,pubsub-subscription
........
.......
env:
- name: PUBSUB_TOPIC
value: "{velocity.v1:pubsub-topic.exports.topic-name}"
- name: PUBSUB_SUB
value: "{velocity.v1:pubsub-subscription.exports.sub-name}"
---
See the following blueprint after these changes: gcp-pubsub.yaml
Verify that the Blueprint is defined without errors:
veloctl env create -f https://raw.githubusercontent.com/techvelocity/velocity-blueprints/main/examples/gcp-pubsub.yaml --dry-run
Requesting the creation of environment loving-ted-forrester with services at 2022-09-21 13:20:22 IDT...
Velocity Resources
Kind Name Validation Depends On
Velocity Service pubsub-subscription Valid pubsub-subscription, pubsub-topic
└─ PubSubSubscription.pubsub.cnrm.cloud.google.com velocity-velo6abw-h3fczwzj-loving-ted-forrester-sub Valid pubsub-subscription, pubsub-topic
Velocity Service pubsub-topic Valid
└─ PubSubTopic.pubsub.cnrm.cloud.google.com velocity-velo6abw-awc6exsp-loving-ted-forrester-topic Valid
Velocity Service service-a Valid pubsub-subscription, pubsub-topic
├─ Deployment.apps service-a Valid pubsub-subscription, pubsub-topic
└─ Service
....
....
Velocity Service properties
Use properties by placing them in templates and embedding them in your deployment files
Syntax: `{velocity.v1:<Velocity Service>.<Property>}`
Example: `{velocity.v1:server.exposures(port=tcp).host}`
Velocity Service Property Resulted Value
service-a exposures(port=http).user
exposures(port=http).password
exposures(port=http).host service-a
exposures(port=http).port 80
exposures(port=http).scheme http
exposures(port=http).uri http://service-a:80
pubsub-subscription exports.sub-name velocity-velo6abw-h3fczwzj-loving-ted-forrester-sub
pubsub-topic exports.topic-name velocity-velo6abw-awc6exsp-loving-ted-forrester-topic
Debug Information
- Set resource `{velocity.v1.generate:cloudResourcePrefix(seed=sub)}-{velocity.v1.envName}-sub` namespace to `loving-ted-forrester`
- Set resource `{velocity.v1.generate:cloudResourcePrefix(seed=topic)}-{velocity.v1.envName}-topic` namespace to `loving-ted-forrester`
- Attaching gcp credentials to `Containerized/apps/v1/Deployment/service-a`
Success
Notice that pubsub-subscription and pubsub-topic have been resolved correctly.