Files
The-transit-Project/.github/agents/azure-deploy/deploy/references/code-deployment-functions-flex.md
T
Sven laptop 635a130f0b
Build and Push Docker Images / detect-changes (push) Successful in 11s
Build and Push Docker Images / build-auth-api (push) Successful in 1m0s
Build and Push Docker Images / build-employee-api (push) Successful in 1m2s
Build and Push Docker Images / build-transit-api (push) Successful in 1m1s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m5s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m13s
Build and Push Docker Images / build-monitoring-ui (push) Successful in 1m15s
Build and Push Docker Images / deploy-test-node (push) Successful in 3s
──────
### Summary of Changes
  1. Documentation Consolidation:
      • Relocated the docs/ folder and all repository .md files (README.md, DEPLOYMENT.md, DOCKER_README.md,
      DOMAINS_README.md, GETTING_STARTED.md, CI_CD_PORTAINER_GUIDE.md, ADMIN_DEPLOYMENT_SUMMARY.md,
      SECURITY_PRIVATE_FILES.md, handoff.md, azure-project-plan.md, plus service-specific READMEs) into .
      • Updated document links in README.md.
  2. AI Agent Project Map:
      • Created PROJECT_MAP.md in the project root containing complete architecture diagrams, service specs, ports, DB
      schemas, environment variables, and developer workflows.
      • Added PROJECT_MAP.md to .gitignore.
  3. Monitoring UI & Infrastructure Integration:
      • Added monitoring_ui service to docker-compose.yml (port 5175).
      • Configured Gitea workflow docker-build.yml for monitoring_ui builds.
      • Added CORS middleware headers in index.js.
      • Added nginx.conf copy step in Dockerfile.

  ──────
  ### Recommended Commit Message

    docs: consolidate project documentation into monitoring_ui and add agent project map

    - Move all markdown documentation files and docs/ folder into monitoring_ui/docs/
    - Update documentation hub index (monitoring_ui/docs/README.md) with relative paths
    - Generate comprehensive AI agent reference map (PROJECT_MAP.md) in repository root
    - Add PROJECT_MAP.md and monitoring_ui build output/env overrides to .gitignore
    - Integrate monitoring_ui service into docker-compose.yml and Gitea CI workflow
    - Configure CORS handling in employee_api for monitoring dashboard access
    ──────
  ### Alternative Short Commit Message

    refactor(docs): move docs to monitoring_ui and create AI agent PROJECT_MAP.md
2026-09-20 23:33:55 +02:00

94 lines
5.8 KiB
Markdown

<!-- azure-cor-disclaimer -->
> **Important:** This skill provides guidance and recommended instructions to assist the AI system. Outputs are not guaranteed to be complete, correct, secure, or applicable to every scenario. Results should be reviewed and validated by a human before being applied. The AI model may choose not to follow all instructions exactly, and additional verification may be required.
# Code Deployment — Azure Functions (Flex Consumption)
How to deploy application code to a **Flex Consumption** function app after its IaC is provisioned. This is a
**different channel** from App Service — read this instead of
[code-deployment-appservice.md](code-deployment-appservice.md) whenever the compute is Functions on Flex
Consumption (the default Functions floor). Only **Functions on Premium (EP1)** use the App Service SCM/Kudu
path.
> ⛔ **`--subscription {subscriptionId}` on EVERY `az` command.**
## The Flex deploy model (why the App Service path does not apply)
Flex Consumption has a **single deployment path**: you build and zip your project, the package is written to a
**blob storage container**, and the app runs from that package on startup. There is **no** Kudu
`SCM_DO_BUILD_DURING_DEPLOYMENT`/Oryx-on-SCM build, **no** `az webapp deploy --type zip`, and **no**
`basicPublishingCredentialsPolicies` (`scm`/`ftp`) enable/re-disable dance. Do not run any of those against a
Flex app — they either error or silently do nothing.
## Deploy the package
Build/zip the project, then deploy with the Functions channel. Prefer a **remote build** for interpreted
runtimes so native wheels/modules are built on Linux, not on the local machine:
```powershell
# Python / Node / TypeScript — zip the PROJECT ROOT (manifest at the zip root) and request a remote build.
az functionapp deployment source config-zip `
--subscription {sub} -g {rg} -n {app} `
--src $zipPath --build-remote true
# .NET (isolated) / Java / Go — deploy a precompiled package (build output at the zip root); no remote build.
az functionapp deployment source config-zip --subscription {sub} -g {rg} -n {app} --src $zipPath
```
`func azure functionapp publish {app}` (Azure Functions Core Tools) is an equivalent channel and also performs
a remote build — use it if Core Tools is already the project's workflow.
- The runtime is fixed by `functionAppConfig.runtime` in IaC — do **not** pass or set `FUNCTIONS_WORKER_RUNTIME`.
- The deploying identity writes the package to the deployment container. With shared-key access disabled, that
identity (the signed-in user for a local deploy, or the CI principal) needs **Storage Blob Data Contributor**
on the deployment storage account, in addition to the function app's own identity role.
- After deploy, sync is automatic; then run the health check below.
## ⛔ Local (non-CI) deploys: hardening can lock you out — do not deny-by-default before first deploy
This pipeline hardens network access, which is CI/CD-friendly but **can block a deploy run from a developer
machine.** Two Flex-specific facts matter:
1. **Flex outbound is a platform-managed gateway pool, not a per-instance IP.** An SCM/site allow rule built
from the deployer's observed public IP (e.g. via ipify) will **not** match the channel's real egress, so it
does not unblock the deploy and often changes between attempts. Do **not** try to punch a `/32` SCM hole to
fix a 403 — it is the wrong lever for Flex.
2. **Model the main site and the deployment/SCM surface independently.** Restricting one must not implicitly
deny the other.
**Rules for the deploy phase:**
- ⛔ **Do NOT set `publicNetworkAccess: 'Disabled'` or a deny-by-default rule on the function app or its
deployment storage BEFORE the first successful code deploy + health check.** Provision with access open,
deploy, verify, *then* harden.
- Before hardening, **tell the user** (once, plainly): *"This deployment hardens network access for
production. Publishing the code from your machine happens first, while access is still open; after the app
is healthy I'll restrict it. If you need to redeploy later from your machine, you may need to temporarily
re-open access or deploy from CI."*
- If a package deploy returns **HTTP 403**, the cause is network hardening applied too early or a missing
Storage Blob Data role — **not** a missing SCM allow rule. Re-open public access on the app + deployment
storage, confirm the deployer's role assignment, redeploy, then re-harden. Never fall back to imperative
provisioning.
- ⛔ **Azure inserts a terminal "Deny all" rule as the last entry of any `ipSecurityRestrictions` /
`scmIpSecurityRestrictions` list — this is the expected default sentinel, NOT an error.** Validation must
treat a trailing deny-all with priority `2147483647` (name `Deny all`/`Explicit deny`) as normal. Only flag
it if there are **no** preceding allow rules AND you intended the surface to be reachable.
## Hardening (only AFTER a healthy deploy)
If the plan calls for a locked-down app, apply `publicNetworkAccess`/IP restrictions as the **last** step,
after the health check passes. Keep the deployment storage reachable by the app identity. Record any access
you re-open for a local deploy so cleanup is idempotent (re-running the step must not error if the rule is
already gone).
## Health check
HTTP GET the function endpoint(s) (max 3 iterations, honoring cold start). A Flex app can take up to ~30s to
initialize on first start; `System.TimeoutException`/gRPC host messages during that window are startup noise,
not deploy failures. Inspect the response body for error patterns (`connection refused`, `MODULE_NOT_FOUND`,
`SET-IN-DEPLOY-PHASE`) — HTTP 200 alone is not proof of health when the app depends on another service.
## Database post-deploy
> ⛔ If the app uses a managed database, run [`database-post-deploy.md`](database-post-deploy.md) for migration
> discovery and execution.