Configuration Guide#
HASTE environments are configured with the Azure Developer CLI. Every setting is
supplied with azd env set <NAME> <value> before azd up; the values are
read by infra/main.bicepparam at provision time and
by the deploy hooks in deploy/. Defaults live in
main.bicepparam, so an unset variable falls back to a sensible value.
This guide documents each configuration mode. For the end-to-end workflow, see
setup/README.md and deployment.md.
Contents#
Core settings
Batch (create vs. bring-your-own)
Batch image tags and pool immutability
Email sender domain
Front Door
Development mode
First-admin bootstrap
Cleaning up an environment
Core settings#
Variable |
Default |
Purpose |
|---|---|---|
|
|
Prefix for all resource names. |
|
|
Per-environment suffix; keeps names unique. |
|
|
Azure region. |
|
— |
APIM publisher email (required). |
|
|
APIM publisher name. |
|
env RG |
Resource group holding bring-your-own shared resources (Batch, ACR). |
|
— |
Shared Azure Container Registry name (without |
Resource names are HASTE_RESOURCE_PREFIX + HASTE_RANDOM_SUFFIX based (not
azd’s resourceToken) so what-if stays clean against existing deployments.
Batch (create vs. bring-your-own)#
HASTE runs GPU workloads on Azure Batch. Both the Batch account and the GPU pool can either be created in the environment resource group or reused from a shared resource group.
Variable |
Default |
Values |
Purpose |
|---|---|---|---|
|
|
|
Create a Batch account in the env RG, or reference a shared one. |
|
— |
account name |
Required when the account mode is |
|
|
|
Create the GPU pool, or reference an existing one. |
|
— |
pool resource id |
Required when the pool mode is |
Additional pool parameters (batchPoolVmSize, batchPoolMaxNodes,
batchPoolSubnetName) have defaults in infra/main.bicep
and can be overridden by adding them to main.bicepparam.
Common combinations:
Self-contained fork —
HASTE_BATCH_ACCOUNT_MODE=CreateandHASTE_BATCH_POOL_MODE=Createcreate a Batch account and a GPU pool in the environment resource group.Shared account, own pool —
HASTE_BATCH_ACCOUNT_MODE=ExistingwithHASTE_BATCH_POOL_MODE=Createcreates only a new named pool on the shared account, in the shared resource group, via a cross-RG-scoped sub-module. It never modifies the account or sibling pools.Shared account and pool — both set to
Existingreference the account and pool for app-settings wiring only; nothing is written to the shared resource group.
When the pool is created on a shared account, review what-if against both
the environment resource group and HASTE_SHARED_RESOURCE_GROUP, and make sure
the deploy identity has pool-write on the shared account.
Email sender domain#
The email backend (Azure Communication Services) is provisioned in-IaC, so its connection string is a deploy-time output rather than a manually pasted secret.
Variable |
Default |
Values |
Purpose |
|---|---|---|---|
|
|
|
Sender-domain strategy. |
|
— |
domain |
Required when the type is |
AzureManaged provisions an
azurecomm.netsender domain with no DNS step — the default, best for forks and quick environments.Custom provisions a custom sender domain. DNS verification (TXT/SPF/DKIM records) lives in the customer’s DNS zone and is an out-of-band, one-time step.
No Key Vault is introduced; the connection string is wired from a listKeys()
output to the Function App settings.
Front Door#
Azure Front Door and its WAF are a feature-flagged module, deployed only when enabled.
Variable |
Default |
Purpose |
|---|---|---|
|
|
Provision Front Door + WAF in front of the app. |
Development mode#
Development mode is a dev-only switch. It must never be true in production.
Variable |
Default |
Purpose |
|---|---|---|
|
|
Anonymous Function auth + auto-provisioning of users as administrators. |
When true, the API uses anonymous auth and GetUserById auto-creates any
unknown caller as an administrator — convenient for local and throwaway
environments, unacceptable for production. When false (the default and the
production setting), Functions are key-protected (the postdeploy hook injects the
host key into the APIM backends) and unknown users are rejected until an admin
adds them.
First-admin bootstrap#
Production uses DEVELOPMENT_MODE=false, so users are managed explicitly and are
not auto-provisioned as administrators. That creates a bootstrap problem: an
admin is needed to add the first users, but a fresh environment has none. The
postdeploy hooks solve it by seeding a first admin.
Variable |
Default |
Purpose |
|---|---|---|
|
signed-in user |
Email of the first administrator. |
Interactive deploys — if
HASTE_FIRST_ADMIN_EMAILis unset, the seed uses the signed-in deployer’s email (deploy/seed-storage-defaults.ps1), writes it intousers_acl.jsonas an administrator, and invites it to the Static Web App (deploy/invite-user.ps1).Non-interactive / CI / service-principal deploys — there is no signed-in user, so set
HASTE_FIRST_ADMIN_EMAIL. Without it, the first-admin seed is skipped and the environment has no administrator.
Both hooks are idempotent (skip-if-exists / dedup). After the first admin signs in, subsequent users are added through the app’s admin user-management flow — the first-admin seed is a one-time bootstrap, not the ongoing mechanism.
Cleaning up an environment#
Deleting an environment does not immediately free its name. APIM, Front Door, and
Batch resources are soft-deleted and retained by Azure for a day or two, so
you cannot reuse the same HASTE_RESOURCE_PREFIX + HASTE_RANDOM_SUFFIX
combination right away.
To tear down and reuse a name sooner:
# Delete the environment's resources.
azd down --force --purge
# APIM must be purged from its soft-deleted state before the name is free.
az apim deletedservice list -o table
az apim deletedservice purge --service-name <name-from-the-list> --location <region>
azd down --purge purges soft-deletable resources it manages; a shared Batch
pool created on a shared account is additive, so remove it explicitly if it
is no longer needed. Otherwise, choose a new suffix and let Azure auto-purge the
old resources.