fix(batch): sync Batch application settings across code and deploy paths - #98
Merged
Merged
Conversation
`hastegeo` reads `AZURE_BATCH_REGISTRY_SERVER`, but every deploy path emitted `AZURE_BATCH_REGISTRY_SERVER_URL`, which no code read. The setting fell back to its `<registry-name>.azurecr.io` placeholder, so image preprocessing failed with `InvalidPropertyValue: The specified registry is an invalid docker registry server name` before any task reached Batch. Separately, `deploy_apps.sh` never emitted the shared-pool settings added with the multi-tenant Batch pools (`AZURE_BATCH_*_POOL_IDS`, `AZURE_BATCH_USE_SAS`, `AZURE_BATCH_MANAGE_POOLS`) or `EMBEDDING_QUEUE_NAME`, so environments deployed through it silently ran the legacy single-pool path against renamed pools. - config: resolve `AZURE_BATCH_REGISTRY_SERVER`, falling back to the deprecated `_URL` name and stripping any scheme, so environments provisioned before the rename keep working while operators migrate. - new `utils/batch_config.py`: fail fast naming the unset application setting, instead of surfacing an opaque Azure error from inside pool creation. Runs at the submission boundary so the message reaches the image layer status. - runner: rebind a reused Batch job whose pool binding is stale. Job ids default to the pool id, and `create_job` only re-enabled an existing job, so spillover was silently ineffective and tasks queued into jobs bound to deleted pools. - runner: whitelist both training and imageryprep images on created pools, matching `infra/modules/batchPool.bicep`. - deploy: emit the full setting set from `deploy_apps.sh` and `functions.bicep`, with per-environment pool overrides that default to legacy behavior. - new `check_env_drift.py` + `config-drift.yml`: fail any PR where a required variable is missing from a deploy path, or a deploy path emits a setting no code reads. Verified to fail on the pre-fix tree and pass after. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dd98b384-7e26-47a9-8c03-6f9594eb611c
jQuinRivero
force-pushed
the
v-joaquinri/fix-batch-config-drift
branch
from
July 27, 2026 13:48
8637f9d to
1cc4ee3
Compare
RC artifacts readyAll branch deployment references use the same RC tag:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Image-layer creation failed in a deployment environment before any task reached Azure Batch:
<registry-name>.azurecr.ioishastegeo's placeholder default — proof the real setting never reached the running app.Root causes
1.
AZURE_BATCH_REGISTRY_SERVERwas read by code but emitted by nothing.hastelib/src/hastegeo/core/config.pyAZURE_BATCH_REGISTRY_SERVER.github/scripts/deploy_apps.shAZURE_BATCH_REGISTRY_SERVER_URLinfra/modules/functions.bicepAZURE_BATCH_REGISTRY_SERVER_URLlocal.settings.example.jsoncAZURE_BATCH_REGISTRY_SERVER_URLAZURE_BATCH_REGISTRY_SERVER_URLwas read by zero lines of Python. Becausedeploy_apps.shre-sets the whole app-settings block on every run, a manual portal fix is clobbered by the next deploy.2.
deploy_apps.shnever emitted the shared-pool settings. The multi-tenant Batch pool work added five settings thatfunctions.bicepsets butdeploy_apps.sh— the script behinddeploy-apps.yml— did not:AZURE_BATCH_{TRAINING,INFERENCE,IMAGERYPREP}_POOL_IDS,AZURE_BATCH_USE_SAS,AZURE_BATCH_MANAGE_POOLS. Environments deployed through it silently ran the legacy single-pool path against renamed pools.EMBEDDING_QUEUE_NAMEwas missing from both paths.3. A reused Batch job stayed pinned to the pool that created it. Job ids default to the configured pool id, and
create_jobonly re-enabled an existing job — it never re-pointed it. So capacity-aware spillover was silently ineffective, and once a pool was renamed or deleted, every task queued into a job bound to a pool that no longer existed.Changes
Code
config.py— resolveAZURE_BATCH_REGISTRY_SERVER, falling back to the deprecated_URLname and stripping any scheme (the Batch SDK wants a bare login server; the legacy setting stored a URL). Dual-read rather than a clean break, so existing deployments keep working until an operator renames the setting.utils/batch_config.py— fail fast naming the unset application setting instead of surfacing an opaque Azure error from inside pool creation. Two tiers: registry settings are only required whenAZURE_BATCH_MANAGE_POOLSis true, so environments on pre-created autoscale pools aren't broken.runners/azure_batch.py— validate at the submission boundary (add_task, not__init__— the runner is constructed eagerly on read-only status paths); rebind a stale job/pool binding; whitelist both training and imageryprep images on created pools, matchingbatchPool.bicep.Deploy paths
deploy_apps.sh+deploy-apps.yml— emit the full setting set, with per-environment pool overrides that default to the previous behavior.functions.bicep(+ regeneratedmain.json),local.settings.example.jsonc.Guard
check_env_drift.py+config-drift.yml— parses the code withastto find every env read, classifies a variable as required when it has no default or its default is still a<placeholder>, and fails when a deploy path is missing it. Also reports the inverse (settings emitted but read by nothing) — the exact signature of a half-applied rename.Verification
main(validated in a clean worktree): flagsAZURE_BATCH_REGISTRY_SERVERand all three*_POOL_IDS, exit 1. Passes on this branch, exit 0.101 passed, 7 skippedlocally; the only non-passing modules need dev deps absent from my local env (pytest-mock,geopandas,shapely).pre-commit runclean on all changed files (black, isort, flake8, detect-secrets).az bicep buildregeneratesmain.json; diff is the two intended settings plus generator-version churn.Operator action required
Existing deployments should rename the
AZURE_BATCH_REGISTRY_SERVER_URLapplication setting toAZURE_BATCH_REGISTRY_SERVER(value: bare login server, e.g.myacr.azurecr.io) on theapiandqueuesFunction Apps. The legacy name still works until then.Also confirm
AZURE_BATCH_TRAINING_POOL_ID/AZURE_BATCH_IMAGERYPREP_POOL_IDname pools that still exist and are identical across both apps — they double as the default Batch job ids, so a mismatch means the api app reads status from a job the queues app never wrote to.Notes
spec/features/batch-config-drift/documents the root causes and design; cross-referencesbatch-compute-expansion, whose deploy wiring was incomplete.deploy_apps.shvsinfra/main.bicep) is out of scope — tracked inspec/features/infra-iac-migration/.