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.
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
We have two Velocity Services,
service-a
and service-b
, that currently DO NOT depend on each other.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
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.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:

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). 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
Notice that the configmap is part of the
service-a
Velocity Service and that we identify the dependency of service-a
on service-b
.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.
In this example, we'll begin with original-service-a.yaml, a simple service with no environment variables.
---
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.
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-env
key: DB_USERNAME
optional: false
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.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}"
Your application needs to reference 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.The resulting
queueUrl
and queueArn
will be resolved at provisioning time to their correct values.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}"
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
.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}"
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
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.The resulting
metadata.name
will be resolved at provisioning time to the correct value.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}"
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}"
---
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.Last modified 2mo ago