Applies to ALL compute targets (App Service, Container Apps, Functions). For Container Apps-specific Bicep patterns (secretRef, identity), see bicep-container-apps.md.
⛔ Never invent env var values — derive from the app’s config class. Cross-reference .env.example, .env.sample, docker-compose.yml, and the app’s config module. Verify each value:
Type validation: URL-typed fields need valid URLs — not * or placeholders
Defaults: Use app defaults unless overriding with deployed URL
Required: Fields without defaults must be provided
Pitfalls:CORS_ORIGINS=["*"] → invalid for strict validators (use actual URLs). DATABASE_URL=changethis → use KV ref. JSON array env vars need Bicep variable escaping:
bicep
var corsOrigins = '["https://${containerApp.properties.configuration.ingress.fqdn}"]'{ name: 'CORS_ORIGINS', value: corsOrigins }
⛔ Chicken-and-egg: CA references KV secrets that don’t exist yet at deploy time. KV secret values (DB connection strings, passwords) are only known AFTER IaC creates the database.
IaC Phase 2: Redeploy Bicep with isPlaceholder=false → activates KV secretRef entries + real image + ACR registries
IaC pattern — reference secrets by name, gated by isPlaceholder:
⛔ Container Apps: KV secretRef entries MUST be gated behind isPlaceholder (see bicep-container-apps.md § Two-Phase Wiring). Phase 1 deploys with secrets: [] because the CA’s managed identity has no RBAC yet. Phase 2 activates KV refs after RBAC propagates.
⛔ Do NOT hardcode secrets in committed files — not in main.parameters.json, terraform.tfvars, env vars, or any generated file. (@secure() Bicep params ARE the correct way to pass a secret at deploy time — the ban is on committing the value, not on the parameter.) The deploy phase seeds secrets into Key Vault via az keyvault secret set after database provisioning — see code-deployment-appservice.md (opens in a new tab) or code-deployment-container-apps.md (opens in a new tab) § Database Post-Deploy.
⛔ Azure managed databases and caches enforce TLS. Local docker-compose configs typically don’t. This mismatch causes container crashes post-deploy.
Check prereq-output.json.warnings[] for warnings with fixPhase: "scaffold". Each warning’s fix field describes the required IaC change. Read the app’s config loader for the actual env var name.
⛔ Prefer env var override over code change. Only modify source if no env override path exists AND user approves.
⛔ Self-review: If any fixPhase: "scaffold" warning exists and IaC lacks the fix → flag as FLAGGED.
⛔ KV secret names allow only alphanumeric characters and hyphens. Map env var names: SECRET_KEY → secret-key, DATABASE_URL → database-url. Do NOT use underscores — Azure rejects them with SecretNameInvalid.
⛔ Azure managed databases only create the administratorLogin user. Docker-compose POSTGRES_USER / MYSQL_USER auto-creates a database user — Azure PostgreSQL/MySQL Flexible Server does NOT. Map compose user env vars to the administratorLogin value from your Bicep, not the compose username.