Scope environment variables per component
Applies to workflow mode.
Overview
In this tutorial you build two components that both read the same environment variable name but can be given different values - one per component - without touching the global variable. You will also see the .env file kdeps scaffolds for each component on first run.
This tutorial is for developers who have completed the Reusable component tutorial. It assumes you know:
- Basic YAML
- How environment variables work
By the end you will be able to:
- Read an environment variable in a component with
env() - Override it for one component with a
{COMPONENT}_{VAR}prefix - Fall back to a component's
.envfile - Understand the auto-scaffolded
.envandREADME.md
Background
When a component runs, env('API_KEY') is resolved in this order:
{COMPONENT_NAME_UPPER}_API_KEYin the process environment (scoped override)- Plain
API_KEYin the process environment API_KEYin the component's own.envfile (lowest priority)
So a translator component and a summarizer component can each get their own key while sharing one variable name in the YAML.
Before you start
- kdeps installed (
kdeps --version). - A working directory for the project.
Step 1: create the structure
mkdir -p envdemo/components/translator
mkdir -p envdemo/components/summarizer
mkdir envdemo/resources
cd envdemoStep 2: two components that read the same variable
Create components/translator/component.yaml:
# components/translator/component.yaml
apiVersion: kdeps.io/v1
kind: Component
metadata:
name: translator
version: "1.0.0"
interface:
inputs:
- name: text
type: string
required: true
resources:
- actionId: translate
name: Translate
exec:
command: "echo"
args:
- "translator using key: {{ env('API_KEY', 'none') }} -- text: {{ input('text') }}"
apiResponse:
success: true
response:
out: "{{ get('translate') }}"Create components/summarizer/component.yaml - identical but with name: summarizer and "summarizer using key: ..." in the echo.
Step 3: call both components
Create resources/01-translate.yaml:
# resources/01-translate.yaml
actionId: runTranslate
name: Run translator
component:
name: translator
with:
text: "hello"Create resources/02-summarize.yaml:
# resources/02-summarize.yaml
actionId: runSummarize
name: Run summarizer
component:
name: summarizer
with:
text: "a long paragraph"Create resources/03-response.yaml:
# resources/03-response.yaml
actionId: response
name: Response
requires: [runTranslate, runSummarize]
apiResponse:
success: true
response:
translator: "{{ output('runTranslate').out }}"
summarizer: "{{ output('runSummarize').out }}"Step 4: add the route
Create workflow.yaml:
# workflow.yaml
apiVersion: kdeps.io/v1
kind: Workflow
metadata:
name: envdemo
version: "1.0.0"
targetActionId: response
settings:
apiServer:
portNum: 16395
routes:
- path: /run
methods: [GET]Step 5: run with scoped keys
kdeps validate .
export KDEPS_API_AUTH_TOKEN=dev-token
# Shared default for both components
export API_KEY=global-key
# Override just the translator
export TRANSLATOR_API_KEY=translate-key
kdeps run .curl "http://localhost:16395/run" -H "Authorization: Bearer $KDEPS_API_AUTH_TOKEN"Response:
{
"success": true,
"data": {
"translator": "translator using key: translate-key -- text: hello",
"summarizer": "summarizer using key: global-key -- text: a long paragraph"
}
}The translator saw TRANSLATOR_API_KEY; the summarizer fell back to API_KEY.
Step 6: inspect the scaffolded files
On the first run kdeps created these (it never overwrites existing ones):
cat components/translator/.env # template listing every env() var, blank
cat components/translator/README.md # generated from component.yaml metadataFill in .env to provide a lowest-priority fallback value when no process environment variable is set.
Summary
You built two components that:
- Read the same variable name with
env('API_KEY') - Resolve it independently:
{COMPONENT}_API_KEY->API_KEY->.env - Got an auto-scaffolded
.envandREADME.mdon first run
Next steps
- Components reference - env derivation,
.envdetails - Reusable component tutorial - building a component
- Global config - named connections with shared credentials
- Jinja2 templates -
env()in YAML preprocessing
