Thursday, November 27, 2025

Zero-Downtime Deployments with Azure App Service Deployment Slots

Deploying directly to a production Azure App Service instance introduces risk: if the new version fails to start or behaves incorrectly under load, users are immediately affected. Deployment slots eliminate this risk by letting you deploy and warm up a new version in a staging environment, then swap it into production in a single atomic operation that takes seconds and does not drop connections.

This post covers creating and configuring deployment slots, managing slot-specific settings, and using traffic splitting for gradual rollouts.

1. How Deployment Slots Work

Each deployment slot is a fully independent instance of your App Service app with its own hostname, configuration, and deployment history. A swap operation exchanges the app content and most of the configuration between two slots — typically staging and production — and Azure handles the traffic cutover internally.

The key property of a slot swap is that it is warm: before traffic is redirected to the incoming slot, Azure sends HTTP requests to the slot's root path and waits for a successful response. This ensures you are not exposing a cold-started or misconfigured instance to production traffic.

Deployment slots are available on the Standard, Premium, and Isolated tiers. The Standard tier supports up to 5 slots per app, which is sufficient for most single-pipeline workflows.

2. Creating a Staging Slot

  1. Navigate to App Service > Deployment slots
  2. Select + Add Slot
  3. Provide a Name (for example, staging)
  4. Under Clone settings from, select the production slot to inherit its current configuration
  5. Select Add

Once created, the staging slot is accessible at https://<app-name>-staging.azurewebsites.net. Deploy your new version to this slot using the same mechanism you use for production — Azure DevOps, GitHub Actions, or the Azure CLI.

Following is the Azure CLI command to deploy a zip package to a specific slot:

az webapp deployment source config-zip \
  --resource-group <resource-group> \
  --name <app-name> \
  --slot staging \
  --src ./release.zip

3. Slot-Specific Application Settings

Some configuration values — database connection strings, feature flags, or external service endpoints — must differ between staging and production. By default, application settings are cloned from the source slot, which is not always the correct behaviour.

Marking a setting as slot-specific prevents it from travelling with the app content during a swap. The setting stays bound to the slot it was configured on.

To mark a setting as slot-specific:

  1. Navigate to App Service > Configuration > Application settings
  2. Add or edit the setting
  3. Check the Deployment slot setting checkbox
  4. Select Save

Following is a practical pattern for slot-specific settings:

SettingStaging valueProduction value
ASPNETCORE_ENVIRONMENTStagingProduction
ConnectionStrings__DefaultConnectionStaging database connection stringProduction database connection string
FeatureFlags__NewCheckoutFlowtruefalse

Settings that are not marked as slot-specific travel with the app content on swap. This is appropriate for settings that represent the app version rather than the environment — for example, an API version identifier or a build number.

4. Swapping Slots to Production

Before performing a swap, validate the staging slot by opening its URL directly and running any smoke tests relevant to the release.

To perform a swap:

  1. Navigate to App Service > Deployment slots
  2. Select Swap
  3. Confirm Source is staging and Target is production
  4. Review the Config Changes tab to confirm which settings will change as a result of the swap
  5. Select Swap

The swap operation completes in under a minute for most apps. Critically, the previous production version is now resident in the staging slot, making rollback trivial: swap again to restore the previous state.

To automate a swap at the end of a deployment pipeline:

az webapp deployment slot swap \
  --resource-group <resource-group> \
  --name <app-name> \
  --slot staging \
  --target-slot production

5. Traffic Splitting for Gradual Rollouts

Rather than switching all traffic at once, you can route a percentage of production requests to the staging slot while the remainder continues to the current production version. This is useful when you want to observe error rates and response times on real traffic before completing the rollout.

  1. Navigate to App Service > Deployment slots
  2. Under the staging slot row, set Traffic % to the desired initial percentage (for example, 10)
  3. Select Save

Azure assigns a session-pinning cookie (x-ms-routing-name=staging) to users routed to the staging slot, so their subsequent requests go to the same slot for consistency.

Increase the percentage incrementally — 10%, 25%, 50% — monitoring error rates in Application Insights at each step. Once satisfied, complete the rollout with a full swap and reset the traffic percentage to 0.

Summary

Deployment slots are the most practical tool Azure App Service provides for reducing deployment risk. Slot-specific settings keep environment configuration cleanly separated, the swap mechanism ensures warm instances are promoted to production, and traffic splitting allows confidence-building on real traffic before full cutover. Adding a staging slot to an existing App Service app takes under five minutes and pays back that time on the first deployment that would otherwise have caused an incident.


Thursday, November 13, 2025

Implementing a FinOps Practice on Azure from Scratch

FinOps is not a tool; it is a cultural practice that brings together engineering, finance, and business teams to manage cloud costs as a shared responsibility. Many organisations deploy Azure resources with strong technical governance but without the financial accountability structures that FinOps requires.

The FinOps Foundation defines three iterative phases: InformOptimize, and Operate. This post maps each phase to concrete Azure tooling and practices that can be adopted incrementally.

1. Phase 1 — Inform: Building Cost Visibility

The Inform phase focuses on ensuring that every team can see the costs they are generating. Without visibility, accountability is not possible.

Key actions in this phase:

  • Enable cost visibility per team — assign the Cost Management Reader role at the resource group or subscription scope to engineering teams so they can see their own costs without requiring finance involvement
  • Enforce resource tagging — deploy an Azure Policy initiative that audits or denies resources missing required tags such as teamenvironment, and cost-center
  • Set up Cost Management Exports — deliver monthly cost data to a storage account for finance integration and historical analysis

Navigate to Cost Management + Billing > Cost Analysis and confirm that costs can be grouped by relevant tags. If tag coverage is below 80%, address tagging before progressing to optimisation.

2. Phase 2 — Optimize: Reducing Waste and Right-Sizing

The Optimize phase focuses on identifying and acting on cost reduction opportunities. Azure Advisor is the primary tool for this phase.

Navigate to Azure Advisor > Cost to review recommendations. Common recommendations include:

  • Shut down or resize underutilised VMs — Advisor flags VMs with average CPU utilisation below 5% over the past 30 days
  • Purchase Reserved Instances — based on consistent usage patterns over the past 30 days
  • Delete unattached managed disks — disks that are not attached to any VM and are accruing storage costs
  • Right-size or eliminate idle App Service plans — plans with no active deployments

Each recommendation includes an estimated monthly savings amount. I recommend triaging these by savings value and addressing the top five recommendations before moving to the next phase.

3. Phase 3 — Operate: Establishing Ongoing Governance

The Operate phase is where FinOps becomes sustainable. It requires regular cadence, clear ownership, and automated controls.

Key actions in this phase:

  • Monthly cost review meeting — a 30-minute review with engineering leads and a finance representative, using Cost Analysis grouped by team tags as the agenda
  • Budget alerts at team level — each team's resource group has a monthly budget with alerts at 80% and 100%, sent directly to the team
  • Anomaly alerts — enabled at subscription scope via Cost Management > Cost alerts > Anomaly alerts to catch unexpected spikes between monthly reviews
  • Chargeback or showback reporting — monthly export data processed and shared with cost-center owners, establishing financial accountability without requiring portal access

4. Starting Small

Attempting to implement all three phases simultaneously typically leads to a governance initiative that stalls. A practical starting point is:

  1. Enable Cost Management Reader for all engineering teams this week
  2. Enforce three mandatory tags via Azure Policy this sprint
  3. Schedule the first monthly cost review for end of month

From there, the Inform phase creates the visibility needed to have meaningful optimisation conversations, while the Operate phase structures those conversations into repeatable habits.

Summary

FinOps on Azure does not require custom tooling or a dedicated team. Azure Cost Management, Azure Advisor, Azure Policy, and a consistent tagging strategy provide everything needed to run a mature Inform → Optimize → Operate cycle. The limiting factor is usually organisational habit, not technical capability.