Message Ops

Use this path when your infrastructure team provisions Azure resources through the Azure Portal or its own tooling. It produces the same supported architecture and follows the same migration-before-runtime gates as Azure Installation. It does not require vendor Terraform.

Have the approved 1.7.1 delivery, subscription/tenant, region, resource names, HTTPS origin, capacity and recovery objectives ready. Your provisioner needs scoped resource/role-assignment rights and private data-plane connectivity. Use the deployment kit’s documentation/INSTALL-MANUAL.md for the corresponding resource-by-resource operator procedure; the release-specific configuration and ordering below apply throughout.

Provision resources before applications

  1. Create or select the resource group and VNet. Use a Container Apps delegated subnet (Microsoft.App/environments), a PostgreSQL delegated subnet (Microsoft.DBforPostgreSQL/flexibleServers) and a separate non-delegated subnet for private endpoints. Use the site’s approved non-overlapping address space.
  2. Create a Premium ACR with admin credentials disabled and public access disabled. Add its registry private endpoint, approved private connection and privatelink.azurecr.io DNS zone/link. Verify both registry and data endpoint resolution from intake and runtime paths.
  3. Create Key Vault with RBAC authorization, purge protection and deny-by-default network access. Add its vault private endpoint and privatelink.vaultcore.azure.net DNS zone/link. Grant the provisioner only the secret-write access needed.
  4. In Azure Database for PostgreSQL flexible servers → Create, select version 16, private networking in its delegated subnet, a linked private DNS zone ending .postgres.database.azure.com, and disabled public access. Choose compute, storage, HA and backup retention against site objectives. Enter the administrator password privately and store it through the approved secret process.
  5. Create database message_ops. In server parameters, allow PGCRYPTO in azure.extensions, preserving any other required extension entries. This must precede migration.
  6. Create the Container Apps environment in its delegated subnet and connect Log Analytics. Configure environment peer-to-peer encryption and the approved network/egress policy. Confirm routes to database, vault, registry, broker, IdP and collectors.
  7. Create two user-assigned managed identities: application and migration. Grant each AcrPull. Give the migration identity Key Vault Secrets User only on its migration database secret. Give the application identity that role only on runtime secrets. Avoid vault-wide grants that collapse this separation.
  8. Store the privileged TLS database URL as the migration secret using a protected file, not command arguments. Use a versionless URI. Publish approved images to ACR and record digests as described in Software Intake.

Assign the identities to the actual workloads as well as granting their roles. Identity does not bypass private networking or firewall rules. Verify both successful reads of permitted secrets and denied reads across the migration/runtime boundary.

Run the migration job

Create a manual Container Apps Job in the environment using the approved API image, migration identity and migration secret. Use the command/arguments in Operator Commands, one parallel replica, one completion, retry limit 0 and a 1,800-second timeout. Its working directory is /app.

Start it, retain the returned execution name and require Succeeded. Verify the application migration ledger, queue schema/queues and runtime-role grants. A successful job creation or image pull is not a successful migration. Correct failures before launching runtime apps.

Then enable the restricted runtime database login and create the runtime URL and required keys using Operator Commands and Configuration Reference. These secrets are separate from the migration credential.

Create the application workloads

Use Single revision mode and the application managed identity for image pulls. In the Portal, select the approved digest-pinned image, assign the identity and configure Key Vault-backed secrets before referencing them in container environment variables.

Create the application workloads
WorkloadIngress and probesRequired configuration
APIInternal HTTP ingress, target 3000, allow internal HTTP. Readiness GET /health/ready on 3000.Runtime database URL, four required keys, NODE_ENV=production, API_PORT=3000, AUTH_MODE=oidc, real broker adapter, public origins, CSRF, proxy settings.
WorkerNo ingress. Readiness GET /health/ready on 9090.Same runtime database, shared SSO/broker keys, NODE_ENV=production, real broker adapter and shared operation/queue controls.
WebExternal HTTPS ingress, target 8080. Readiness GET / on 8080.API_UPSTREAM is the API’s bare internal ingress FQDN, without scheme or :3000.

Keep RUN_MIGRATIONS_ON_BOOT=false on API and Worker as the deployment marker; neither runs DDL. Start with the resource allocations in Azure Installation, then size against measured workload. API/Worker run as UID 65532 and have no shell; Web runs non-root on 8080.

Azure ingress terminates browser TLS. For a custom domain, bind the certificate and ensure WEB_BASE_URL, CORS, callback, WebAuthn origin and RP ID all use that hostname. Preserve the supplied nginx proxy and security-header configuration. The reference path has three trusted proxy hops; use actual trusted CIDRs and verify IP allowlist behavior from permitted and denied sources.

Supply private database CA settings to all database clients if required. Messaging CA trust is stored in the environment profile. Node HTTPS trust for SEMP/IdP/collectors uses an optional mounted PEM with NODE_EXTRA_CA_CERTS; it does not override the SSO/collector endpoint address restrictions.

Complete and accept the installation

Run the separate one-time administrator bootstrap with the runtime identity and mounted password. Remove the temporary job/secret after successful sign-in. Follow Application Setup and all installation verification checks.

Configure registry diagnostics and role assignments before applying a registry deletion lock. A registry-scoped role/diagnostic maintenance change can require controlled unlock, change and relock. A private endpoint is a separate resource and does not inherit that registry lock. Keep images referenced by current and recovery revisions.

Record network paths, identities, secret names, image digests, backup retention and restore-drill results in your operational record. Later image upgrades must still run the matching migration job first; see Upgrade and Recovery.

Confirm