infra/main.bicep:
Why one warm replica? Traffic is a handful of calls per day plus the
orchestrator ping, but the calls that matter are the customer’s — a
forecast POST arriving on a scaled-to-zero app pays a cold start, and one
arriving in the scale-in drain window gets a
503. minReplicas: 1
removes both; max one replica keeps the file-based state single-writer.Bootstrap
The ACR doesn’t exist until the template runs, so the first deployment uses a placeholder image and then swaps in the real one:1
Deploy the infrastructure
2
Build the image in ACR (no local Docker needed)
3
Point the app at the real image
appFqdn.Continuous deployment
The manual GitHub Actions workflowdeploy.yml
runs the same ACR build + app update. It needs:
- repository secret
AZURE_CREDENTIALS(service principal with contributor on the resource group), - repository variables
AZURE_RESOURCE_GROUPandAZURE_NAME_PREFIX.
Security posture
- Two scoped API keys:
EXTERNAL_API_KEY(hand to the customer; forecast ingestion only) andPROCESS_API_KEY(internal pipeline + orchestrator timer)./healthstays open for probes. - Secrets live as Container Apps secrets — move to Key Vault references when the team standardizes on it.
- Before live Engrate submissions, set the real balancing-group EICs
(
AREA_MARKET_IDS) and the ECC counterparty EIC. The bridge starts against Engrate staging (ENGRATE_ENVIRONMENT=staging, submissions carry Engrate’stestflag); going live is one switch — store the production key inENGRATE_PRODUCTION_API_KEYand setENGRATE_ENVIRONMENT=production(also possible at runtime from the console’s Engrate tab). - If the customer calls from fixed egress IPs, add ingress IP restrictions on the Container App.