Skip to content

Settings and environment variables

Set by Pulumi on the Web App

Variable Purpose
IS_AZURE_ENVIRONMENT Enables Azure-specific settings
SCM_DO_BUILD_DURING_DEPLOYMENT Oryx build on deploy
PRE_BUILD_COMMAND Bootstrap curl
POST_BUILD_COMMAND cicd/post_build.sh
DISABLE_*_BUILD Disable unrelated Oryx detectors
DISABLE_COLLECTSTATIC Defer collectstatic to startup
HEALTH_CHECK_PATH /health-check
WEBSITE_HEALTHCHECK_MAXPINGFAILURES Azure health-check threshold (10); set explicitly so it does not drift
DJANGO_SETTINGS_MODULE Your settings module
DJANGO_SECRET_KEY Random 50-char string
DJANGO_ALLOWED_HOSTS Comma-separated hosts from HostDefinitions
DJANGO_HOSTS_MAP JSON host→aliases when aliases exist
AZURE_KEY_VAULT Vault name
AZURE_STORAGE_ACCOUNT_NAME Storage account
AZURE_STORAGE_CONTAINER_MEDIA / _STATICFILES Blob containers
CDN_HOST / CDN_PROFILE / CDN_ENDPOINT CDN wiring
DB_HOST / DB_NAME / DB_USER Postgres connection
REDIS_SIDECAR When Redis enabled
DJANGO_TASKS When tasks enabled
DJANGO_RQ_CRON When RQ cron scheduler enabled
RQ_CRON_CONFIG Path to consumer cron config (default: cron_config.py)
AZURE_COMMUNICATION_SERVICE_ENDPOINT When ACS enabled
WEBSITE_HTTPLOGGING_RETENTION_DAYS When retention > 0
{ENV}_SECRET_NAME Key Vault secret names from secrets=
ACCESS_BLOCK_ENABLED Per-site: true by default from Pulumi; false when access_block=False
ACCESS_BLOCK_QUEUE_URL Stable add-only queue SAS URL (fixed start/expiry; rotates with the storage key)
ACCESS_BLOCK_RESOURCE_GROUP Resource group for ARM access-rule updates
ACCESS_BLOCK_SUBSCRIPTION_ID Subscription ID for ARM access-rule updates
plus Consumer environment_variables

Azure also injects WEBSITE_HOSTNAME (and others).

Read by pulumi_django_azure.settings

Also consumed when present:

  • BLOCK_SUSPICIOUS_PATHS (bool, default true when IS_AZURE_ENVIRONMENT) — block hardcoded scanner path patterns
  • BLOCK_EMPTY_USER_AGENT (bool, default true when IS_AZURE_ENVIRONMENT) — reject requests with missing/empty User-Agent
  • DJANGO_DEFAULT_FROM_EMAIL
  • AZURE_CACHE_CONTROL (default long-lived immutable)
  • REDIRECT_ALIASES (bool, default true)
  • CICD_SCRIPTS_BRANCH (bootstrap; not settings.py)

Email (MAILERS)

When AZURE_COMMUNICATION_SERVICE_ENDPOINT is set (Pulumi does this when ACS is enabled for the site), settings configure Django 6.1 MAILERS:

MAILERS = {
    "default": {
        "BACKEND": "django_azure_communication_email.EmailBackend",
        "OPTIONS": {"endpoint": "<from AZURE_COMMUNICATION_SERVICE_ENDPOINT>"},
    },
}

On Azure, AZURE_TENANT_ID is also set so the backend can authenticate with DefaultAzureCredential (managed identity). Set DJANGO_DEFAULT_FROM_EMAIL for the sender address. When ACS is not enabled, no MAILERS entry is added — override with your own mailer locally or in the consumer settings module.

Scanner probe blocking (SuspiciousRequestBlockMiddleware)

Registered by patch_django_settings_for_azure on Azure when either BLOCK_SUSPICIOUS_PATHS or BLOCK_EMPTY_USER_AGENT is true (both default on). Inserted before SecurityMiddleware.

Always exempt: HEALTH_CHECK_PATH, paths under /.well-known/.

Path rules (when BLOCK_SUSPICIOUS_PATHS=true, case-insensitive):

Rule Examples
Dot-prefixed path segment /.env, /.git/config, /vendor/.env
Suffix .php, .asp, .aspx, .jsp, .cgi, .sql, .bak, .rb
Prefix /wp-, /cgi-bin/, /phpmyadmin, /administrator/, /vendor/phpunit, /drupal, /joomla, /laravel, /symfony, /magento, /prestashop, /typo3, /actuator, /containers/, /server-status, /server-info
Contains /phpunit/

User-Agent (when BLOCK_EMPTY_USER_AGENT=true): block if User-Agent is missing, empty, or whitespace-only.

Blocked requests return HTTP 404 and log at DEBUG on pulumi_django_azure.security with reason=suspicious_path or reason=empty_user_agent.

Client IP resolution

RequestLogContextMiddleware and access-block enqueue use client_ip_from_request:

  1. Azure front-end headers (overwritten by App Service, not spoofable): Client-IP, then X-Client-IP, then X-ARR-CLIENTIP
  2. First non-loopback hop in X-Forwarded-For (skips forged 127.0.0.1 prefixes scanners often send; Azure appends the real client)
  3. REMOTE_ADDR

Ports in Azure-style values (e.g. 203.0.113.10:54321) are stripped before logging or Deny rules.

Automated access block (SuspiciousRequestAccessBlockMiddleware)

When ACCESS_BLOCK_ENABLED=true and ACCESS_BLOCK_QUEUE_URL is set (Pulumi default for add_django_website), suspicious requests are enqueued for the shared access-block Function. See Automated access block.

Setting Default
ACCESS_BLOCK_ENABLED true on each Web App from Pulumi (unless access_block=False)
ACCESS_BLOCK_QUEUE_URL (from Pulumi when access block is enabled for that site)

Rate threshold, window, TTL escalation, and the 500-rule cap are configured on the Function app, not in Django.

Helper

patch_django_settings_for_azure(INSTALLED_APPS, MIDDLEWARE, TEMPLATES) — see Django app.

Runtime clients

When configured:

  • AZURE_KEY_VAULT_CLIENT — Key Vault SecretClient
  • AZURE_CREDENTIAL / storage token credential via managed identity helpers in azure_helper.py