The supported v1.7.1 production platform is Azure Container Apps with Azure Database for PostgreSQL Flexible Server 16. Use the matching deployment kit and approved prebuilt images. The shipped Terraform provisions infrastructure; it does not build images, publish them or automatically run migration jobs. If your organization does not permit vendor Terraform, use Manual Azure Installation.
Prerequisites
Record the installation owner, administrator, subscription/tenant, region, browser HTTPS hostname, capacity, recovery objectives and maintenance window. Arrange license issuance after the installation ID exists. There is no seeded administrator, password or license.
The operator host needs Terraform 1.11 or later with the release’s provider lock files, Azure CLI with the Container Apps extension, jq, PostgreSQL 16 client tools and private network/DNS access to the registry, vault and database. Offline intake additionally needs the tools in Software Intake. Do not install tools inside production API/Worker images: they have no shell or package manager.
Prepare an encrypted, access-controlled remote Terraform backend before the first apply. The shipped roots do not configure one. Protect state, plans and real tfvars; do not commit them. The provisioner needs resource creation, scoped role-assignment rights, backend access and vault secret-write rights. Network access and Azure identity permissions are separate requirements.
Network and workloads
| Component | Required deployment contract |
|---|---|
| Web | External HTTPS ingress to container port 8080. |
| API | Internal HTTP ingress to container port 3000; not a public origin. |
| Worker | No ingress; platform health probes on 9090. |
| Migration | Manual single-replica job using the API image and a separate privileged identity/secret. |
| PostgreSQL | Version 16, delegated private subnet and DNS; public access disabled; PGCRYPTO allowed. |
| ACR | Premium/private endpoint, managed-identity pulls, admin user disabled. |
| Key Vault | RBAC, purge protection, private endpoint, deny-by-default access. |
Use separate delegated subnets for Container Apps and PostgreSQL, plus a non-delegated private-endpoint subnet. Link privatelink.azurecr.io and privatelink.vaultcore.azure.net DNS zones to the network; the PostgreSQL private zone must end in .postgres.database.azure.com. Verify DNS/routes from both workloads and the operator host.
Allow DNS, database TCP 5432, registry/vault HTTPS, approved IdP/OTLP destinations and the brokers’ configured SEMP and messaging ports. The reference enables environment peer-to-peer encryption, but does not supply blanket subnet egress isolation. Private-endpoint NSG hardening is opt-in and needs site-specific allow/deny testing. Do not assume a private endpoint alone implements network segmentation.
Web forwards /api/ and /health to the API’s bare internal ingress FQDN, without :3000. Internal API ingress allows HTTP for that path; public browser TLS terminates at Azure ingress. The reference uses TRUST_PROXY=true and three trusted hops. Narrow trusted proxy ranges to actual subnets and verify source-IP handling before using IP allowlists.
Select the deployment root
From the extracted offline bundle root described in Software Intake, choose one delivered directory:
terraform/environments/prodfor newly provisioned infrastructure.terraform/examples/existing-landing-zonefor existing resource group, subnets, registry, vault, DNS and Log Analytics.
For a new installation, change into the root before running the commands below:
cd terraform/environments/prod
For an existing landing zone, use cd terraform/examples/existing-landing-zone from the bundle root instead. If a separately supplied deployment kit has a different layout, use its delivered manifest/README to locate the equivalent root; do not assume a product source-checkout path.
Both create the application database and Container Apps environment. Copy that root’s terraform.tfvars.example, replace its placeholders and retain the release’s provider lock files. Start from the complete example rather than treating the partial snippets below as a full configuration.
Default workload sizing is a starting point, not a throughput guarantee:
| Workload | CPU | Memory | Min/max replicas |
|---|---|---|---|
| API | 1 vCPU | 2 GiB | 2 / 6 |
| Worker | 1 vCPU | 2 GiB | 1 / 4 |
| Web | 0.5 vCPU | 1 GiB | 1 / 3 |
| Migration job | 0.5 vCPU | 1 GiB | One completion |
Load-test against your message sizes and broker limits. Increasing Worker concurrency or replicas increases broker work; maximum replica bounds alone do not promise backlog-driven autoscaling.
1. Provision infrastructure only
For a new installation, set:
deploy_migration_job = false
deploy_container_apps = false
api_image = null
worker_image = null
web_image = null
runtime_db_credential_secret_id = null
runtime_db_credential_secret_name = null
api_additional_secrets = {}
worker_additional_secrets = {}
Run in the selected root after configuring its backend:
terraform init
terraform plan -out=installation.tfplan
terraform apply installation.tfplan
Review the plan before applying and protect the saved plan. Confirm private endpoints/DNS, database extension allowance, registry, vault and both managed identities. The application identity gets ACR pull and runtime-secret access; the migration identity gets ACR pull and access only to the migration credential. Test both allowed and denied secret access without printing values.
The staging flags control resource existence. Setting either to false on a running installation can destroy apps/jobs; it is not a maintenance pause. Defaults in the shipped example are true, so override them deliberately for first installation.
2. Publish images and create the migration job
Complete Software Intake. Set api_image to your approved ACR digest and deploy_migration_job=true; keep deploy_container_apps=false. Review a new plan and apply it.
The job must use /nodejs/bin/node, the compiled migration entrypoint, NODE_ENV=production and the privileged database secret. The reference invocation, execution tracking and checks are in Operator Commands. Run the job and require the named execution to succeed before continuing. API and Worker never repair missing migrations at startup.
3. Enable the runtime login and create secrets
After migration creates the restricted message_ops_app role, follow Runtime Database Login to enable it, set a password securely, verify grants and store its distinct TLS URL in Key Vault. The runtime credential is not generated by Terraform.
Create the four API encryption/signing keys and share the appropriate two with Worker. Use versionless secret URIs; do not place secret values in tfvars or ordinary environment maps. Configure private CA trust on every database client if needed, including migration/bootstrap jobs. Follow Configuration Reference and Configuration Examples.
4. Activate API, Worker and Web
Set all three approved image digests, runtime-secret references and required origins. Use AUTH_MODE=oidc, SOLACE_ADAPTER=real on both services and enabled CSRF protection. Set deploy_container_apps=true, keep deploy_migration_job=true, review a new plan and apply.
Keep the latest revision active and verify its actual image and health. An older healthy revision does not establish that the new release started successfully.
5. Bootstrap and hand over
Use the one-time Administrator Bootstrap job with the runtime database credential and a mounted temporary password secret. It creates an account, not a session. Deliver the HTTPS URL, administrator email, password through an approved private channel, license issuance details and support contact.
The application administrator completes Application Setup: sign-in, MFA, license, sign-in policy, broker environments, scoped users/automation and settings. Do not provide Azure/database credentials to ordinary application users.
6. Verify installation
Set WEB_URL to your public HTTPS origin without a trailing slash:
curl --fail --silent --show-error "$WEB_URL/"
curl --fail --silent --show-error "$WEB_URL/health/ready"
curl --fail --silent --show-error "$WEB_URL/api/v1/auth/methods"
Expect the UI, readiness JSON and authentication-method JSON respectively. Verify the latest API/Worker/Web revisions, exact image digests and readiness probes. API readiness checks database availability, exact migration ledger, compatible queue schema and configured queues; it does not prove broker connectivity or every permission. Worker readiness also requires its consumer to be initialized.
With an ordinary scoped account, verify sign-in/MFA, license, environment test, VPN/queue listing, bounded message search and permitted payload access. On an approved test queue, submit an operation, inspect its final item outcomes and confirm audit visibility. Confirm telemetry when enabled and perform a database restore drill against your recovery objectives.
Record actual results, revision/execution names and digests. These checks must be performed in your installation before service acceptance. Use Troubleshooting for failures and Upgrade and Recovery for later changes.