Pre-deployment checklist
1
Create the App Service
Provision a Linux App Service running Python 3.12. The production artifact vendors Set HTTPS-only on the resource:
manylinux_2_28_x86_64 Python wheels, so the OS must be Linux.2
Enable managed identity
Enable a system-assigned managed identity:Or, if you prefer a user-assigned identity, assign it to the App Service and note its client ID — you will set
FLUX_MANAGED_IDENTITY_CLIENT_ID in a later step.3
Grant RBAC to the managed identity
Flux needs two permission sets on every subscription it will query.Reader — for Azure Resource Graph (inventory, Advisor, Policy):Microsoft.CostManagement/*/read — for Cost Management queries. The deployed custom FinOps Platform Reader role includes this permission and is the recommended assignment:Repeat both assignments for every subscription Flux will query, or assign at a shared management-group scope. RBAC propagation can take several minutes.
4
Enable App Service Authentication (Easy Auth)
In the Azure portal, open the App Service → Authentication → Add identity provider → choose Microsoft.Use the Flux app registration (the same registration used for app roles below). Configure:
- Require authentication — redirect unauthenticated browser requests to Microsoft.
- Restrict issuer — set the token issuer URL to
https://login.microsoftonline.com/<tenant-id>/v2.0to reject tokens from other tenants. - Ensure no network path bypasses App Service Authentication. The application trusts
X-MS-CLIENT-PRINCIPALonly because App Service removes external copies and injects its validated value.
5
Create and assign Flux app roles
On the Entra app registration, define two app roles:
Assign users or groups through the Enterprise application blade. Flux maps:
Flux.Reader→ read-only dashboard, inventory, and opportunities.Flux.Admin→ all reader access plus integration configuration and synchronization.
FLUX_ENTRA_ADMIN_ASSIGNMENTS and FLUX_ENTRA_READER_ASSIGNMENTS.6
Set required application settings
In Configuration → Application settings, set these minimum required values:
For a user-assigned identity, also set:
A system-assigned identity requires no client ID setting.
7
Select the provider and synchronize
Once the App Service is running:
- Open Integrations in the Flux UI.
- Add the tenant ID and one or more subscription IDs.
- Select App Service managed identity.
- Save, then select Synchronize now.
https://management.azure.com/.default and begins paginated inventory, Advisor, and Cost Management collection.Application settings reference
Set these in App Service → Configuration → Application settings. The pipeline applies non-secret settings additively on every deploy, preserving Key Vault references configured out-of-band.Secret settings —
FLUX_DEEPSEEK_API_KEY, LM_BEARER_TOKEN, FLUX_OPENROUTER_API_KEY, FLUX_WIKI_API_TOKEN — must be provisioned as Azure Key Vault references out-of-band. The deployment pipeline applies non-secret settings additively with az webapp config appsettings set and will never overwrite Key Vault references.DuckDB persistence
DuckDB is the Flux analytical database. By default it is stored atdata/flux.duckdb relative to the application root, but on App Service this path is inside wwwroot, which is replaced on every ZIP deploy.
In production, always set:
/home mount is App Service persistent storage — it survives redeployments and instance restarts. The deployment pipeline migrates any existing database to this path automatically on first deploy and enables WEBSITE_RUN_FROM_PACKAGE=1 so the ZIP is mounted read-only.
Configure co-located paths for all other file-backed state:
WebJob architecture
Production Flux uses external sync worker mode (FLUX_SYNC_WORKER_MODE=external). In this configuration:
- The web process is a read-only consumer in snapshot mode. It enqueues sync requests and serves the API, but never opens DuckDB as a writer.
- A singleton continuous WebJob (
flux-sync-worker) claims queued sync requests fromsync_runsunder an execution lease. Only one worker instance runs at a time; if the worker exits, the OS sync lease is released and the replacement worker recovers the unfinished request. - Independent scheduled WebJobs enqueue focused requests for inventory, intelligence, cost history, FOCUS ingestion, retail prices, Advisor, LogicMonitor discovery and metrics, FinOps Toolkit data, and right-sizing due-checks. All DuckDB writes are serialized through the one worker.
Production gaps checklist
Before go-live, address each of these items:- Validate Easy Auth end-to-end. Confirm app-role assignments, managed identity, and subscription RBAC are working in the target App Service before opening access to users.
- Eliminate bypass routes. Ensure the application cannot be reached through any network path that bypasses Easy Auth — including internal routes, SCM hostnames, and IP-restricted origins.
-
Connect health monitoring. Wire the
/api/healthand/api/operations/health(admin) endpoints to an approved notification destination for operational alerting. -
Monitor LogicMonitor warm-up. Track the incremental LogicMonitor collector through its first 14-day rolling-history warm-up and tune
FLUX_LOGICMONITOR_METRIC_BATCH_SIZEagainst observed API rate limits. -
Assign a non-human identity for smoke tests. Before enabling the authenticated branch of the production smoke script in CI, assign a dedicated
Flux.Readerservice principal — do not use a human account. - Complete AI model procurement review. Before wider use of Flux Intelligence, complete model-service procurement and privacy review, adversarial evaluation, stakeholder acceptance criteria, distributed budget enforcement, and service-failover design.