| name | auto-lambda-env |
| description | Set environment variables on AI automation Lambda functions. Interactively collects secrets and operational values, then applies them via AWS CLI. Reads function names and pre-filled values from .ai/automation/infra.json. |
| when_to_use | Use when setting environment variables on Lambda functions, when onboarding a new project (API keys, org URLs), or when the user says 'set Lambda env vars', 'configure Lambda secrets', 'update automation credentials'. |
| argument-hint | |
You set Lambda environment variables for the AI automation agents. There are 2 consolidated router Lambda functions: WI Router (work-item webhook events) and PR Router (pull-request webhook events). Values are collected interactively (secrets are never written to files). Applies all variables in a single aws lambda update-function-configuration call per function.
0. Prerequisites
Read .ai/automation/infra.json. Check automationProfile:
- If
consumer (or legacy pr-only/pr-delegation): "This repo uses the consumer profile — Lambda environment variables are managed by the hub project. Do NOT modify Lambda env vars from this repo." STOP.
source .ai/lib/audit.sh
export AUDIT_LOG_PREFIX=infra
Pre-fill these from infra.json (don't ask for values already known):
DYNAMODB_DEDUPE_TABLE ← storage.dynamodb.dedupe.tableName
DYNAMODB_RATE_LIMIT_TABLE ← storage.dynamodb.rateLimits.tableName
SQS_DLQ_URL ← storage.sqs.dlq.queueUrl
ADO_DOD_PIPELINE_ID ← pipelines.dod.id (WI Router)
ADO_QA_PIPELINE_ID ← pipelines.qa.id (WI Router)
ADO_DEV_PIPELINE_ID ← pipelines.devagent.id (WI Router)
ADO_DOC_PIPELINE_ID ← pipelines.docagent.id (WI Router)
ADO_ESTIMATION_PIPELINE_ID ← pipelines.estimation.id (WI Router)
ADO_PR_ANSWER_PIPELINE_MAP ← JSON map of repo→pipeline-id (PR Router)
ADO_ORG_URL ← adoOrg (PR Router)
MY_IDENTITIES ← from infra.json if set (PR Router)
1. Collect Secrets
Ask these one at a time — these cannot be pre-filled from infra.json:
ADO Personal Access Token? (secret — Lambda env var ADO_PAT) This PAT needs: Work Items read, Code read, Pull Requests read+contribute, Project read.
Webhook basic auth username? (Lambda env var BASIC_USER) Example: automation-webhook. Must match what you'll set in ADO Service Hooks.
Webhook basic auth password? (secret — Lambda env var BASIC_PASS) Suggest generating: openssl rand -base64 24
Webhook secret? (secret — Lambda env var WEBHOOK_SECRET) Suggest generating: openssl rand -base64 32
DoD trigger tag? (Lambda env var TAG_GATE_DOD — WI Router) Default: KAI-DOD-AUTOMATION
QA trigger tag? (Lambda env var TAG_GATE_QA — WI Router) Default: KAI-QA-AUTOMATION
DevAgent trigger tag? (Lambda env var TAG_GATE_DEV — WI Router) Default: KAI-DEV-AUTOMATION
DOCAgent trigger tag? (Lambda env var TAG_GATE_DOC — WI Router) Default: KAI-DOC-AUTOMATION
Estimation trigger tag? (Lambda env var TAG_GATE_ESTIMATION — WI Router) Default: KAI-ESTIMATION-AUTOMATION
SimpleAgent has no trigger tag here. SimpleAgent is not Lambda-routed — it uses an Azure-native Service Hook (@kai-simple comment) configured by /auto-webhooks. Do not ask for a TAG_GATE_SIMPLE.
2. Apply to WI Router Lambda
The WI Router (<PREFIX>-WI-Router) handles tagged work-item webhook events and routes to the appropriate pipeline (DoD, QA, DevAgent, DOCAgent, Estimation) based on tag gates. DoR and BugFix are NOT routed here — they use Azure-native @kai-dor / @kai-bugfix comment hooks (no Lambda).
WI_ROUTER_FUNC=$(python3 -c "import json; print(json.load(open('.ai/automation/infra.json'))['lambdas']['wi-router']['functionName'])")
REGION=$(python3 -c "import json; print(json.load(open('.ai/automation/infra.json'))['region'])")
aws_lambda_config "$WI_ROUTER_FUNC" \
--environment "Variables={
ADO_PAT=<secret>,
BASIC_USER=<user>,
BASIC_PASS=<secret>,
WEBHOOK_SECRET=<secret>,
ADO_DOD_PIPELINE_ID=<pipeline-id>,
ADO_QA_PIPELINE_ID=<pipeline-id>,
ADO_DEV_PIPELINE_ID=<pipeline-id>,
ADO_DOC_PIPELINE_ID=<pipeline-id>,
ADO_ESTIMATION_PIPELINE_ID=<pipeline-id>,
TAG_GATE_DOD=<tag>,
TAG_GATE_QA=<tag>,
TAG_GATE_DEV=<tag>,
TAG_GATE_DOC=<tag>,
TAG_GATE_ESTIMATION=<tag>,
DYNAMODB_DEDUPE_TABLE=<table>,
DYNAMODB_RATE_LIMIT_TABLE=<table>,
SQS_DLQ_URL=<url>
}" \
--region "$REGION"
SimpleAgent routing (WI Router tag map)
The WI Router routes tagged work-item events to pipelines via a tag-to-pipeline-ID lookup. After this skill runs, the WI Router's effective routing table includes:
{
"KAI-DOD-AUTOMATION": "<dod-pipeline-id>",
"KAI-QA-AUTOMATION": "<qa-pipeline-id>",
"KAI-DEV-AUTOMATION": "<devagent-pipeline-id>",
"KAI-DOC-AUTOMATION": "<docagent-pipeline-id>",
"KAI-ESTIMATION-AUTOMATION": "<estimation-pipeline-id>"
}
SimpleAgent is NOT Lambda-routed
SimpleAgent is not part of the WI Router (its AGENTS array has no simple entry). Its pipeline (ado-cli-simple.yml) is triggered by an Azure-native Service Hook — a comment containing @kai-simple → an Incoming WebHook service connection → the pipeline's resources.webhooks listener (configured by /auto-webhooks, not here). No TAG_GATE_SIMPLE / ADO_SIMPLE_PIPELINE_ID env vars are needed. SimpleAgent reads its own config from pipeline variables (set by /auto-pipelines — AEM_QA_URL, AEM_QA_USER, AEM_QA_PASSWORD, MCP version pins).
3. Apply to PR Router Lambda (merge-safe)
The PR Router (<PREFIX>-PR-Router) handles all pull-request webhook events. It uses ADO_PR_ANSWER_PIPELINE_MAP (JSON map of repo→pipeline-id) for routing PR answer events to the correct pipeline.
PR_ROUTER_FUNC=$(python3 -c "import json; print(json.load(open('.ai/automation/infra.json'))['lambdas']['pr-router']['functionName'])")
aws_lambda_config "$PR_ROUTER_FUNC" \
--environment "Variables={
ADO_PAT=<secret>,
BASIC_USER=<user>,
BASIC_PASS=<secret>,
WEBHOOK_SECRET=<secret>,
ADO_ORG_URL=<adoOrg>,
ADO_PR_ANSWER_PIPELINE_MAP=<json-map>,
MY_IDENTITIES=<identities>,
DYNAMODB_DEDUPE_TABLE=<table>,
DYNAMODB_RATE_LIMIT_TABLE=<table>,
SQS_DLQ_URL=<url>
}" \
--region "$REGION"
Important: aws lambda update-function-configuration replaces ALL env vars. Always read current env vars first and merge changes, preserving existing secrets and table names.
4. Verify
for FUNC in "$WI_ROUTER_FUNC" "$PR_ROUTER_FUNC"; do
echo "=== $FUNC ==="
aws lambda get-function-configuration \
--function-name "$FUNC" --region "$REGION" \
--query 'Environment.Variables' --output json | python3 -c "
import sys, json
d = json.load(sys.stdin)
for k in sorted(d.keys()):
print(f' {k}: [set]')
"
done
5. Summary Report
## Lambda Environment Variables Set
| Variable | WI Router | PR Router |
|----------|-----------|-----------|
| ADO_PAT | ✓ | ✓ |
| BASIC_USER | ✓ | ✓ |
| BASIC_PASS | ✓ | ✓ |
| WEBHOOK_SECRET | ✓ | ✓ |
| ADO_DOD_PIPELINE_ID | ✓ | — |
| ADO_QA_PIPELINE_ID | ✓ | — |
| ADO_DEV_PIPELINE_ID | ✓ | — |
| ADO_DOC_PIPELINE_ID | ✓ | — |
| ADO_ESTIMATION_PIPELINE_ID | ✓ | — |
| ADO_PR_ANSWER_PIPELINE_MAP | — | ✓ |
| ADO_ORG_URL | — | ✓ |
| MY_IDENTITIES | — | ✓ |
| TAG_GATE_DOD | ✓ | — |
| TAG_GATE_QA | ✓ | — |
| TAG_GATE_DEV | ✓ | — |
| TAG_GATE_DOC | ✓ | — |
| TAG_GATE_ESTIMATION | ✓ | — |
| DYNAMODB_DEDUPE_TABLE | ✓ | ✓ |
| DYNAMODB_RATE_LIMIT_TABLE | ✓ | ✓ |
| SQS_DLQ_URL | ✓ | ✓ |
**Audit log:** `.ai/logs/infra.<week>.jsonl`
### Next step
`/auto-webhooks` — Configure ADO service hooks
Examples
-
/auto-lambda-env — Reads infra.json for function names and pre-filled values (DynamoDB table names, SQS URL, S3 bucket). Asks interactively for secrets (ADO PAT, Anthropic API key). Merges with existing env vars and applies to both WI-Router and PR-Router Lambda functions.
-
/auto-lambda-env (adding a consumer repo's pipeline ID) — Reads current env vars from WI-Router Lambda, adds a new entry to ADO_PR_ANSWER_PIPELINE_MAP for the consumer repo's PR Answer pipeline. Preserves all existing values and applies the merged configuration.
-
/auto-lambda-env (updating expired ADO PAT) — Asks for the new ADO PAT value. Reads current env vars, replaces only the ADO_PAT value, and applies to both Lambda functions. All other env vars remain unchanged.
Troubleshooting
-
"update-function-configuration replaces ALL env vars" warning
Cause: AWS Lambda's update API replaces the entire environment variable set, not individual values.
Fix: The skill always reads current env vars first and merges changes. If env vars are missing after an update, re-run /auto-lambda-env to restore them. Check the audit log for what was applied.
-
Pipeline ID mismatch warning
Cause: An existing ADO_*_PIPELINE_ID value differs from the new value being set.
Fix: Review the warning message — it shows old vs new values. If the pipeline was re-created, confirm the update. If the IDs should match, check /auto-pipelines output for the correct ID.
-
Secret values appearing in logs
Cause: This should not happen — the skill only logs env var keys, never values.
Fix: Check that you're using /auto-lambda-env (which uses audit wrappers) and not raw aws lambda update-function-configuration commands. The audit log records the operation but not secret values.
Rules
- Always source audit.sh first —
aws_lambda_config is an audit wrapper
- Never print secret values — only list env var keys when verifying
- Never write secrets to infra.json — only non-secret pre-filled values come from infra.json
- Ask one question at a time — never combine
- Derive pre-filled values from infra.json — minimise questions to user
- Read before write —
update-function-configuration replaces ALL env vars. Always read current env vars first and merge changes
- Warn on pipeline ID overwrite — if an existing
ADO_*_PIPELINE_ID differs from the new value, warn the user: "Pipeline ID will change from to . Proceed?" Skip if values match.