Environment configuration deployment slots mismatched between staging and production

Deployment slot configurations in ado-2025 environment management are showing mismatches between staging and production slots. Our release pipeline deploys successfully to staging, but production deployments fail due to configuration drift.

The Bicep template defines:

resource appService 'Microsoft.Web/sites@2022-03-01' = {
  properties: {
    siteConfig: {
      appSettings: [
        { name: 'ENVIRONMENT', value: 'production' }
      ]
    }
  }
}

When we promote from staging to production slot, the ENVIRONMENT variable doesn’t update, causing application runtime errors. We’ve verified that the slot-specific configuration settings are marked as ‘sticky’, but the swap operation doesn’t respect these settings. Has anyone successfully implemented slot configuration management with proper drift detection in Azure DevOps environment deployments?

Your environment configuration challenges require systematic infrastructure-as-code practices and runtime validation.

Bicep Template Parameterization: Your current template doesn’t properly define deployment slots as separate resources. Expand your Bicep template to include explicit slot definitions:

resource appService 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceName
  properties: {
    siteConfig: {
      appSettings: baseAppSettings
    }
  }
}

resource stagingSlot 'Microsoft.Web/sites/slots@2022-03-01' = {
  parent: appService
  name: 'staging'
  properties: {
    siteConfig: {
      appSettings: union(baseAppSettings, [
        { name: 'ENVIRONMENT', value: 'staging' }
        { name: 'SLOT_NAME', value: 'staging' }
      ])
    }
  }
}

Define slot-specific settings using parameter files for each environment. The union() function merges base settings with slot-specific overrides, ensuring consistent configuration structure across slots.

Environment Slot Configuration Management: Implement slot configuration as a two-phase deployment:

Phase 1 - Infrastructure deployment (Bicep template)

Phase 2 - Runtime configuration (Azure CLI)


az webapp config appsettings set \
  --resource-group ${resourceGroup} \
  --name ${appServiceName} \
  --slot staging \
  --settings ENVIRONMENT=staging \
  --slot-settings ENVIRONMENT

The --slot-settings parameter marks settings as sticky, preventing them from swapping. Apply this configuration immediately after Bicep deployment completes but before any slot swap operations.

Configuration Drift Detection and Remediation: Implement a validation stage in your release pipeline that compares deployed configuration against source-controlled parameter files:

// Drift detection script (PowerShell)
$currentConfig = az webapp config appsettings list \
  --name $appName --slot $slotName --output json | ConvertFrom-Json

$expectedConfig = Get-Content ./parameters/prod-config.json | ConvertFrom-Json

$drift = Compare-Object $currentConfig $expectedConfig -Property name,value
if ($drift) {
  Write-Error "Configuration drift detected"
  # Remediation: Reapply expected configuration
  az webapp config appsettings set --settings @parameters/prod-config.json
}

Run this validation before and after slot swaps to ensure configuration integrity. Store drift detection results in pipeline artifacts for audit purposes.

Slot Swap Strategy: Your swap failures occur because slot-specific settings aren’t properly initialized in both slots. Before executing slot swaps, verify:

  1. All sticky settings exist in both source and target slots
  2. Non-sticky settings match expected post-swap state
  3. Application health checks pass in staging slot
  4. Configuration drift detection shows zero discrepancies

Implement a pre-swap validation task:

{
  "task": "AzureCLI@2",
  "inputs": {
    "scriptType": "pscore",
    "scriptLocation": "inlineScript",
    "inlineScript": "az webapp deployment slot swap --slot staging --name $(appServiceName) --dry-run"
  }
}

The --dry-run flag shows what configuration changes would occur without executing the swap, allowing validation before committing to the operation.

Multi-Release Coordination: For concurrent deployments, implement deployment locks using Azure Resource Manager locks or pipeline environment approvals. Configure exclusive lock mode on your production environment in Azure DevOps, ensuring only one release can deploy at a time. This prevents configuration race conditions when multiple releases target the same slots simultaneously.

Consider using Azure App Configuration service instead of slot-specific app settings. This centralizes configuration management and provides built-in versioning and feature flags. Your application reads configuration from App Configuration at runtime, eliminating the need for slot-specific settings entirely. This approach also solves the drift detection problem since all configuration is stored in a service with audit trails and change tracking.

Slot-specific settings need to be configured outside your Bicep template. The template deploys infrastructure, but slot settings are runtime configuration. Use Azure CLI or PowerShell tasks in your pipeline to set slot-specific app settings after the Bicep deployment completes. This ensures settings don’t get overwritten during slot swaps.

Configuration drift detection requires comparing your desired state (defined in source control) against actual deployed configuration. Implement a pipeline stage that queries the current slot configuration using Azure REST API and compares it against your parameter files. If drift is detected, either fail the deployment or automatically remediate by reapplying the correct configuration. This prevents unexpected configuration changes from propagating through slot swaps.

We do have separate pipeline tasks for slot configuration, but they run before the swap operation. Should we be setting slot-specific configurations after the swap instead? Also, how do we prevent configuration drift when multiple releases deploy to the same environment within a short timeframe?