Pull Key Vault secrets into vertex .env - #3588
Conversation
Add a "Pull secrets from Key Vault" step to the prod and staging frontend deployment workflows. Each step uses az keyvault secret show to retrieve the environment JSON (prod-env-vertex / sta-env-vertex), writes it to secrets.json, and converts it with jq into KEY=VALUE lines at src/vertex/.env before building and pushing the Docker image. This injects the Vertex service environment variables at build time using the repository's KEYVAULT and az/jq tooling.
📝 WalkthroughWalkthroughBoth production and staging deployment workflows standardize Key Vault secret materialization. Analytics-platform now pipes secrets directly to ChangesKey Vault secret materialization workflow
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the Azure staging and production deployment workflows for the Vertex Next.js app to ensure client-side NEXT_PUBLIC_* environment variables are available at Docker/Next.js build time, preventing baked-in localhost:3000 redirects in deployed environments.
Changes:
- Add an Azure Key Vault secret extraction step in the Vertex build job for staging.
- Add an Azure Key Vault secret extraction step in the Vertex build job for production.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| .github/workflows/deploy-frontend-to-azurestaging.yml | Adds a Key Vault pull step before building the Vertex Docker image on staging. |
| .github/workflows/deploy-frontend-to-azureprod.yml | Adds a Key Vault pull step before building the Vertex Docker image on production. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - name: Pull secrets from Key Vault | ||
| run: | | ||
| az keyvault secret show \ | ||
| --vault-name ${{ env.KEYVAULT }} \ | ||
| --name sta-env-vertex \ | ||
| --query value -o tsv > secrets.json | ||
|
|
||
| jq -r 'to_entries | .[] | "\(.key)=\(.value|tojson)"' secrets.json > src/vertex/.env |
| - name: Pull secrets from Key Vault | ||
| run: | | ||
| az keyvault secret show \ | ||
| --vault-name ${{ env.KEYVAULT }} \ | ||
| --name prod-env-vertex \ | ||
| --query value -o tsv > secrets.json | ||
|
|
||
| jq -r 'to_entries | .[] | "\(.key)=\(.value|tojson)"' secrets.json > src/vertex/.env |
Stream `az keyvault secret show --query value -o tsv` directly into `jq` instead of writing to a temporary `secrets.json` file in the Azure deploy workflows. Updated both prod and staging workflows for the next-platform and vertex secret steps so they write directly to `src/platform/.env` and `src/vertex/.env`. This simplifies the steps and removes unnecessary file I/O without changing behavior.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
.github/workflows/deploy-frontend-to-azurestaging.yml (2)
236-242:⚠️ Potential issue | 🟠 Major | ⚡ Quick winThis workflow-only fix will not deploy either staging image on merge.
Lines 236-242 and 282-288 add the missing
.envgeneration, but thecheck_filesgate only enables these jobs forsrc/platform/*,src/vertex/*, orworkflow-trigger. Since this PR only changes.github/workflows/..., merging intostagingskips both jobs and leaves the current staging images untouched.Minimal fix in `check_files`
while IFS= read -r file do echo $file + if [[ $file == .github/workflows/deploy-frontend-to-azurestaging.yml ]]; then + echo "run_analytics_platform=true" >>$GITHUB_OUTPUT + echo "run_vertex=true" >>$GITHUB_OUTPUT + fi + if [[ $file == src/website/* ]]; then echo "run_website=true" >>$GITHUB_OUTPUT fiAlso applies to: 282-288
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy-frontend-to-azurestaging.yml around lines 236 - 242, The workflow adds .env generation steps ("Pull secrets from Key Vault") but the existing check_files gating logic (the check_files job/condition) only allows changes in src/platform/*, src/vertex/*, or workflow-trigger to enable the staging-image jobs, so merging only workflow changes will skip the jobs and not deploy updated staging images; fix by updating the check_files patterns to also include '.github/workflows/**' (or add a workflow-only pattern like '**/.github/workflows/**' or a dedicated 'workflow-trigger' match) so the jobs that run the "Pull secrets from Key Vault" steps are triggered on workflow-only changes.
236-242:⚠️ Potential issue | 🟠 MajorHarden the
az | jqsecret-to-.envpipeline (and note the staging gating behavior)
- Lines 236-242 and 282-288: the workflow’s default shell behavior doesn’t enable
pipefail, so a failingaz keyvault secret showcan still let the step succeed ifjqexits 0—potentially writing an empty/partial.env. Addpipefail(e.g.,defaults: run: shell: bashorshell: bash) and makejqfail on empty output (e.g.,jq -e …) or explicitly validate the generated file is non-empty.- Staging rebuild gating: the
checkjob only flipsrun_analytics_platformforsrc/platform/*andrun_vertexforsrc/vertex/*(orworkflow-trigger), so a PR that changes only this workflow file won’t run these staging rebuild jobs.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy-frontend-to-azurestaging.yml around lines 236 - 242, The step that pipes az keyvault secret show into jq can succeed despite az failing because the default shell lacks pipefail; update the job to use bash with pipefail (e.g., set the run shell to bash or add set -o pipefail) and make jq fail on empty input (use the jq -e form or otherwise assert non-empty output) and/or add an explicit check that src/platform/.env is non-empty after generation; additionally, adjust the check job gating logic so changes to the workflow itself trigger the staging rebuild flags (include this workflow file in the check job path filters or explicitly set run_analytics_platform and run_vertex when workflow-trigger/this workflow is the changed file) to ensure staging rebuilds run when only the workflow is modified..github/workflows/deploy-frontend-to-azureprod.yml (1)
168-174:⚠️ Potential issue | 🟠 MajorFail fast if Key Vault returns no/failed secret (both analytics-platform + vertex).
The workflow doesn’t set
shell:on theserunsteps, so they run withbash -e {0}(nopipefail). Ifaz keyvault secret show ...fails or returns nothing, the pipeline can still succeed becausejq -rexits0on empty input—leaving an empty.envthat Docker builds may proceed with.Suggested hardening
- name: Pull secrets from Key Vault + shell: bash run: | + set -euo pipefail az keyvault secret show \ --vault-name ${{ env.KEYVAULT }} \ --name prod-env-next-platform \ --query value -o tsv | \ - jq -r 'to_entries | .[] | "\(.key)=\(.value|tojson)"' > src/platform/.env + jq -er 'to_entries | .[] | "\(.key)=\(.value|tojson)"' > src/platform/.env + test -s src/platform/.envApply the same changes to the vertex step (
prod-env-vertex/src/vertex/.env) as well.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy-frontend-to-azureprod.yml around lines 168 - 174, The run step that pulls Key Vault secrets for prod-env-next-platform (writing to src/platform/.env) can silently succeed with an empty file because jq exits 0 on empty input and the step runs without pipefail; update the two secret steps (prod-env-next-platform and prod-env-vertex which writes src/vertex/.env) to fail fast by enabling pipefail (set shell to bash -eo pipefail or add set -o pipefail at the top of the run block) and validate the az output before piping to jq (e.g., capture az output, check it's non-empty / az succeeded, and exit non-zero if empty) so the step errors when Key Vault returns nothing or az fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/deploy-frontend-to-azureprod.yml:
- Around line 168-174: The run step that pulls Key Vault secrets for
prod-env-next-platform (writing to src/platform/.env) can silently succeed with
an empty file because jq exits 0 on empty input and the step runs without
pipefail; update the two secret steps (prod-env-next-platform and
prod-env-vertex which writes src/vertex/.env) to fail fast by enabling pipefail
(set shell to bash -eo pipefail or add set -o pipefail at the top of the run
block) and validate the az output before piping to jq (e.g., capture az output,
check it's non-empty / az succeeded, and exit non-zero if empty) so the step
errors when Key Vault returns nothing or az fails.
In @.github/workflows/deploy-frontend-to-azurestaging.yml:
- Around line 236-242: The workflow adds .env generation steps ("Pull secrets
from Key Vault") but the existing check_files gating logic (the check_files
job/condition) only allows changes in src/platform/*, src/vertex/*, or
workflow-trigger to enable the staging-image jobs, so merging only workflow
changes will skip the jobs and not deploy updated staging images; fix by
updating the check_files patterns to also include '.github/workflows/**' (or add
a workflow-only pattern like '**/.github/workflows/**' or a dedicated
'workflow-trigger' match) so the jobs that run the "Pull secrets from Key Vault"
steps are triggered on workflow-only changes.
- Around line 236-242: The step that pipes az keyvault secret show into jq can
succeed despite az failing because the default shell lacks pipefail; update the
job to use bash with pipefail (e.g., set the run shell to bash or add set -o
pipefail) and make jq fail on empty input (use the jq -e form or otherwise
assert non-empty output) and/or add an explicit check that src/platform/.env is
non-empty after generation; additionally, adjust the check job gating logic so
changes to the workflow itself trigger the staging rebuild flags (include this
workflow file in the check job path filters or explicitly set
run_analytics_platform and run_vertex when workflow-trigger/this workflow is the
changed file) to ensure staging rebuilds run when only the workflow is modified.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5696876f-dcd2-4bf6-8ee7-0d8eb88811f8
📒 Files selected for processing (2)
.github/workflows/deploy-frontend-to-azureprod.yml.github/workflows/deploy-frontend-to-azurestaging.yml
🐛 Description
This PR resolves a critical "split-brain" environment issue affecting the Vertex application on Staging and Production.
The Bug: When a user attempted to use Social Login (e.g., Google) on the deployed environments, the browser would incorrectly attempt to redirect them to
http://localhost:3000/...instead of the correctstaging-vertex/vertexAPI URL. Email login, however, continued to work.🔍 Root Cause Analysis
Next.js requires client-side environment variables (prefixed with
NEXT_PUBLIC_) to be present during the build process so they can be statically baked into the browser's JavaScript bundle.Upon auditing our Azure CI/CD workflows, we discovered a missing step in the
vertexDocker build job. While other services (likeanalytics-platform) correctly pulled their secrets from Azure Key Vault to generate a.envfile beforedocker build, thevertexblock completely skipped this step.Because the Docker build environment lacked these secrets, Next.js fell back to its default development variables, permanently hardcoding the
localhost:3000API fallback into the frontend code. (Email login succeeded because NextAuth runs dynamically on the server at runtime, where variables were properly injected).🛠️ Solution
Added the missing Azure Key Vault secret extraction step to the
vertexdeployment jobs in both Staging and Production Azure workflows.Files Modified:
.github/workflows/deploy-frontend-to-azurestaging.yml.github/workflows/deploy-frontend-to-azureprod.ymlChanges Made:
Inserted the following step immediately before
docker buildto ensure the container has access to the.envfile during the Next.js compilation phase: