Skip to content

Latest commit

 

History

History
293 lines (198 loc) · 11.8 KB

File metadata and controls

293 lines (198 loc) · 11.8 KB

Deployment

Deployment model

The supported deployment path uses the Azure Developer CLI (azd) and Bicep. It provisions a new resource group per azd environment, remotely builds three images in Azure Container Registry, deploys Container Apps, and runs database migrations as a one-shot Container Apps Job.

No Azure resource is shared or expected to exist before deployment.

Prerequisites

Tools

  • Azure Developer CLI 1.25 or later
  • Azure CLI
  • Git
  • Node.js 22 or later for hooks and local validation
  • Docker only for local image builds
  • access to an External ID tenant and the council workforce tenant when AUTHENTICATION_MODE is entra or hybrid

Verify:

azd version
az version
node --version

Azure permissions

The deployment creates resources and Azure role assignments. The deploying principal normally needs:

  • Contributor on the subscription or target scope; and
  • User Access Administrator for role assignments.

An Owner assignment includes both capabilities but is broader than necessary. Follow the organisation's privileged-access process rather than granting standing access solely for this sample.

Resource providers

Ensure these providers can be registered:

  • Microsoft.App
  • Microsoft.ContainerRegistry
  • Microsoft.DBforPostgreSQL
  • Microsoft.Cache
  • Microsoft.Storage
  • Microsoft.KeyVault
  • Microsoft.CognitiveServices when AI is enabled
  • Microsoft.OperationalInsights
  • Microsoft.Insights
  • Microsoft.ManagedIdentity
  • Microsoft.Network

The deploying principal can check registration with:

az provider show --namespace Microsoft.App --query registrationState -o tsv

Capacity and policy preflight

Before azd up, confirm:

  1. the intended region is allowed by Azure Policy;
  2. PostgreSQL Standard_B1ms and Azure Managed Redis Balanced_B0 are available;
  3. Container Apps environment and managed-environment quota is available;
  4. required tags and naming policies are understood;
  5. public-endpoint or private-network policies do not conflict with the development profile;
  6. when AI is enabled, gpt-4.1-mini version 2025-04-14 supports Global Standard in the selected AI region and sufficient token quota exists.

Model availability changes independently of the application region. Keep AZURE_OPENAI_LOCATION separate from AZURE_LOCATION.

Deploy a new environment

Authenticate and run:

azd auth login
azd up

azd prompts for:

  • environment name;
  • subscription;
  • primary location.

Use a short environment name such as dev, test01, or pilot. It becomes part of resource names and tags.

Deploy from a setup package

The standalone customer installer produces one ZIP containing the validated deployment project, a secret-free council package, and local launchers.

On Windows, extract the ZIP and double-click:

Install-DigitalPermitPlatform.cmd

The launcher checks/installs Microsoft prerequisites with permission, validates the package, signs the deployment owner in locally, configures non-secret azd values, runs azd provision --preview, and asks for explicit confirmation before deployment. It writes a non-secret deployment-result.json receipt when complete.

Technical operators can still run npm run setup:deploy -- --package "/path/to/council-setup.zip". Pass --plan for no-change validation or --subscription <guid> to pin the target subscription.

See Hosted installer and council setup for the complete three-phase journey and identity boundaries.

What the hooks do

The preprovision hook creates missing values once per environment:

  • DATABASE_PASSWORD
  • NEXTAUTH_SECRET
  • DEMO_PASSWORD
  • default AI, branding, and seed settings
  • default demo authentication mode and disabled Entra placeholders

Existing values are never changed by the hook. Secret values are not printed. For entra and hybrid, the hook fails unless all External ID and workforce tenant, client, and secret values are configured.

The postdeploy hook starts the migration job, overrides SEED_DEMO_DATA for that execution, and waits for Succeeded. Deployment fails if migrations fail or exceed 30 minutes.

Configure before deployment

Set bootstrap values after azd env new and before azd up, or update them and rerun azd up.

azd env set NEXT_PUBLIC_APP_NAME "Example Council Permit Platform"
azd env set NEXT_PUBLIC_SUPPORT_EMAIL "permits@example.gov.uk"
azd env set NEXT_PUBLIC_SUPPORT_PHONE "0300 123 4567"
azd env set NEXT_PUBLIC_DEMO_MODE true
azd env set NEXT_PUBLIC_SHOW_SAMPLE_BANNER true
azd env set SEED_DEMO_DATA true

Use SEED_DEMO_DATA=false outside demonstration environments. Demo mode is a UI flag; it is not a security boundary.

Complete the in-app setup

After migrations and the web application are healthy, open <SERVICE_WEB_URI>/setup. Public bootstrap values are used only until an administrator applies a council profile.

The browser keeps an unfinished draft locally. In-app Setup controls only the presentation and resident-service configuration:

  • council and service identity;
  • landscape logo, branding and support contacts;
  • an explicit public-impact publication gate with an atomic audit record.

Azure resources, region, identity, AI and deployment settings are not shown or editable in the main application. For those changes, use the separate customer installer or controlled azd and identity workflows. Module availability is managed separately through Admin > Modules. Retain the setup ZIP as a reviewed configuration record; it contains no secrets.

Load the local licensing policy

After the first application deployment, a manager or administrator uses Licensing policy to upload the authority's approved local Statement of Licensing Policy. The application accepts PDF, DOCX, Markdown and text files up to 50MB, preserves the complete source file, and creates an inactive draft. PDFs are reviewed in the original embedded document viewer and can also be opened or downloaded. Activating the reviewed version switches Policy Copilot and application insight together without a redeployment and without a policy-length gate. Add each later adopted edition or revision as a new draft; previously active versions are retained for audit and rollback.

Text extraction is an internal search aid, not a replacement copy of the policy. Policy Copilot retrieves a bounded set of relevant excerpts for each request rather than sending the complete statement to the model. Scanned/image-only PDFs remain valid official records but need a text-based replacement or OCR before AI features can use them.

Do not enable policy-grounded AI for service users until the authority has tested representative retrieval and citations against the retained original. Scanned/image-only PDFs can be used as official records immediately, but require OCR or a text-based replacement before enabling AI grounding.

Configure end-user identity

The default azd up path uses synthetic demo credentials for evaluation. For a new production-intent environment, use one guided command instead:

npm run setup:identity -- --external-tenant <tenant-id-or-domain> --deploy

When necessary, it creates/selects the azd environment and runs azd provision in demo-disabled placeholder mode to derive SERVICE_WEB_URI without deploying or seeding the application. It then derives the workforce tenant, creates both app registrations and service principals, creates and associates the applicant user flow, configures workforce roles and assignment enforcement, stores credentials in azd, switches to entra, disables demo data and performs the first azd up. Follow Identity for required directory roles, a no-change preview and manual fallback.

Do not enable entra until both client credentials are set. Bicep stores them in Key Vault; only the web Container App receives versionless secret references.

Enable optional AI

azd env set ENABLE_AI true
azd env set AZURE_OPENAI_LOCATION uksouth
azd env set AZURE_OPENAI_CAPACITY 10
azd up

If deployment reports unavailable model, SKU, or quota, select a supported region or update the model definition in infra/modules/platform.bicep after validating application compatibility.

Deployment outputs

Inspect the environment:

azd env get-values

Important non-secret outputs include:

Output Meaning
AZURE_RESOURCE_GROUP Environment resource group
SERVICE_WEB_URI Public application URL
WEB_APP_NAME Web Container App
WORKER_APP_NAME Worker Container App
MIGRATIONS_JOB_NAME Manual migration job
AZURE_CONTAINER_REGISTRY_NAME ACR name
AZURE_STORAGE_ACCOUNT_NAME Storage account
AZURE_KEY_VAULT_NAME Key Vault
AZURE_OPENAI_ENDPOINT Empty when AI is disabled

Never share azd env get-values output without reviewing it; an azd environment also contains generated secrets.

Update an environment

Application-only change

azd deploy

This rebuilds and deploys all three services and runs the postdeploy migration job.

Deploy one service only when no schema or shared configuration changed:

azd deploy web

Infrastructure change

azd provision
azd deploy

Run Bicep validation and review the planned cost/security impact before provisioning shared environments.

Database migration

Add a checked-in Prisma migration; do not use prisma db push for managed environments.

npm run db:migrate -- --name describe_change
azd deploy

The migration image contains Prisma CLI and the checked-in migration directory. The job applies prisma migrate deploy before optional seed commands.

Validate without deploying

npm ci
npm run db:generate
npm run lint
npm run typecheck
npm test
npm run build
npm audit --audit-level=low
az bicep restore --file infra/main.bicep
az bicep build --file infra/main.bicep
azd show --no-prompt

Subscription-aware az deployment sub validate requires concrete values in place of the azd substitutions in infra/main.parameters.json.

CI/CD

The included validation workflow does not deploy Azure resources. For environment deployment:

  1. use workload identity federation instead of a client secret;
  2. scope the deployment identity to the target subscription or resource group;
  3. protect production with GitHub environments and required reviewers;
  4. run validation before azd provision or azd deploy;
  5. keep environment secrets in the CI environment, not repository variables;
  6. retain deployment and migration evidence.

Use azd pipeline config only after reviewing the generated permissions and workflow against organisational policy.

Cleanup

Delete an environment with:

azd down --purge

Confirm that no required data or backups remain only in the environment. Key Vault purge protection intentionally prevents immediate permanent deletion until its retention window expires.

Remove local azd environment metadata separately when it is no longer needed:

azd env delete <environment-name>

Deployment limitations

  • The default is a development topology, not a multi-region production topology.
  • PostgreSQL uses password authentication, with the password held in Key Vault. Evaluate Microsoft Entra-only database authentication for production.
  • Redis uses access-key authentication held in Key Vault. Evaluate Microsoft Entra authentication and disable keys where the client/runtime design supports token refresh.
  • Redis, Storage, Key Vault, ACR, and optional OpenAI retain public service endpoints in the default profile.
  • Synthetic demo users and data are enabled by default for accelerator exploration.
  • Migration seeding is idempotent but should be disabled for production datasets.

See Security and Operations before adapting the template for production.