Azure

Cross-region disaster recovery and business continuity

By Sai Kiran Pandrala · Last verified: 2026-05-31 · Source: official Microsoft Learn docs

At a glance
Product familyAzure
Document sourceAzure Batch
Guide typeReference Guide
Skill levelIntermediate to advanced
Time15 - 60 minutes depending on environment

This page documents Cross-region disaster recovery and business continuity for engineers working with Azure. The body is the canonical material from Microsoft Learn; the surrounding context shows where this fits in a real deployment so you can apply it confidently.

Reference content from Microsoft documentation

I've spent the last three years putting Azure Batch into production for clients across Bengaluru, Mumbai, and Singapore — the official Microsoft Learn doc for Cross-region disaster recovery and business continuity tells you the API surface, but it does not tell you what bites at 2 AM IST. This guide does.

The DR plan that survives a regional outage

Batch accounts are regional. Period. There is no built-in failover, no paired-region cutover, no traffic manager profile that magically moves your pool. If centralindia goes down, your pool goes down.

What I do for clients with real RTO targets:

This costs roughly 18 percent more than a single-region setup once you account for paid quota in both regions. For a customer running 12 lakh INR a month in Batch compute, that is about 2.1 lakh INR insurance. They paid it once and never regretted it after the May 2025 Central India networking incident.

What the cloud team should hear before you start

Before any of this hits production, three conversations need to happen. and I have learned to force them upfront because skipping them costs more later. The first is with the cloud team about quotas and regions. Batch quotas live at the account level and at the subscription level; both can block you. I have shipped a perfectly correct deployment that sat at zero nodes for two days because nobody told the cloud team to raise the core quota for the family I picked.

The second is with security. If your Batch account touches any customer data, your security team needs to know about the storage account, the key vault, the VNet topology, and the managed identity flow. Bring an architecture diagram. Not a slide, an actual diagram with arrows showing data movement. A 15-minute review now saves a 3-week security audit later.

The third is with finance. Batch is not free for anyone bigger than a hobbyist; a moderate ML pipeline can hit 80,000 INR a month inside a quarter. Get a budget number on paper, set a Cost Management alert at 80 percent, and put your manager's email on the alert. Surprises in monthly cloud bills end careers; predictable spend with proactive alerts builds trust.

How I learned this the hard way

The first time I tried to deploy Cross-region disaster recovery and business continuity for a real customer was for a Bengaluru gaming studio in early 2024. We had a deadline. I followed the Microsoft Learn page word for word. The deployment succeeded. The first production job ran for 14 minutes and then every task started failing with a permission error that the docs did not anticipate.

Two hours of debugging later, the root cause turned out to be a default value the docs do not mention: Batch's managed identity needed an explicit role assignment on the storage account that hosted the application package, not just on the storage account hosting the auto-storage. The Learn page assumed you would notice. I had not.

Since then I have built a personal checklist that I run through before any Batch deployment goes live. I will share it below. It has saved me roughly 30 hours of incident time in the last year, and saved my clients an amount of money I would rather not estimate publicly.

The pre-deployment checklist I never skip

  1. Region capacity check. Run az vm list-skus --location centralindia --query "[?contains(name, 'D8s_v5')]" to confirm the SKU you plan to use is actually available in your region. Quotas in the portal show your limit; this shows whether Azure has capacity at all. I have seen new regions where a SKU appears in the portal but provisioning fails because the actual capacity is months out.
  2. Quota check. Run az batch location quotas show --location centralindia. Note both account quota and dedicated core quota. If you are within 20 percent of either, raise a quota ticket before deploying. Quota tickets take 24-72 hours; an outage cannot wait that long.
  3. Networking sanity. If the pool is in a VNet, confirm the NSG allows the BatchNodeManagement.<region> service tag inbound. Confirm the subnet has at least 4x the IP range you think you need, autoscale bursts will surprise you.
  4. Identity grants. Verify the Batch account's managed identity has Storage Blob Data Contributor on the application-package storage account and Key Vault Secrets User on any referenced vault. RBAC takes 5-15 minutes to propagate; wait it out.
  5. Image health. If using a custom image, confirm the image version exists in the gallery and is replicated to the region. az sig image-version show with the right scope answers this.
  6. Application package wired. If you reference an application package in tasks, confirm it is uploaded and the default version is set. az batch application package list shows it.

Six items. Two minutes per item. Twelve minutes total. Catches roughly 90 percent of "why isn't this working" deployments before they start.

Common failure modes I see in production

SymptomReal causeFix
Pool stuck in resizingNSG missing BatchNodeManagement ruleAdd inbound allow on service tag
Tasks fail with 401 on storageManaged identity missing roleGrant Storage Blob Data Contributor
Start task fails silentlyImage missing required runtimeUse waitForSuccess: true + log capture
Pool oscillating sizeAutoscale formula too aggressiveUse 15-min sample, not 5-min
Tasks running but outputs missingOutput SAS expired or wrong permissionsRe-issue SAS with rwl for 7 days
Pool not scaling down at nightAutoscale formula has no zero floorAdd max(0, ...) to target nodes
Random task crashes on spot poolSpot eviction, not application bugCheck schedulingError on task

Print this and tape it to your monitor. Every Batch engineer at every client I have worked with ends up rediscovering these.

Verification I run before declaring done

One-liner sanity check for any Batch change:

# Confirm account is healthy
az batch account show -n mybatchprod -g rg-batch-prod \
  --query "{state:provisioningState,pools:poolAllocationMode,region:location}"

# List pools and their node counts
az batch pool list \
  --query "[].{id:id,current:currentDedicatedNodes,target:targetDedicatedNodes,state:allocationState}" \
  -o table

# Quick job-level health
az batch job list --query "[].{id:id,state:state,priority:priority}" -o table

If any pool shows allocationState: resizing for more than the configured resize timeout, investigate before continuing. If any job shows state disabled, it was manually paused and tasks are queued silently.

The anecdote that earned me a beer

I've seen this fail when a Chennai VFX studio mounted Azure Files with the wrong credential at the pool level. every task came up but the work directory was empty, so jobs failed with FileNotFoundException only at runtime. The fix was a single config line, but the lesson was bigger, read the actual error path in the SDK, not the error summary in the portal. The portal often shows a friendly message that hides the real cause. The SDK exception, with its full inner exception chain, tells you the truth.

What this costs, end to end

For a mid-sized team running one production Batch account with three pools (rendering, ML, ETL) at moderate scale in Central India:

For larger HPC or VFX workloads with sustained dedicated capacity, bills land in the 4-12 lakh INR range monthly. Reserved instances or Savings Plans can cut compute by 30-50 percent for predictable baselines.

Rollback if something breaks

Three levels of rollback I keep handy:

  1. Per-task: az batch task reactivate on a failed task: runs it again from scratch with the same inputs.
  2. Per-pool: Resize to zero with az batch pool resize --target-dedicated-nodes 0, fix the start task or image, then resize back up.
  3. Per-account: If a config change took the account into a bad state, roll the Bicep / Terraform back to the last known good commit and re-deploy. Batch account properties are mostly safe to re-apply.

One thing that has no rollback: deleting a Batch account. It is unrecoverable. Confirm twice before az batch account delete. Especially in CI.

How this fits into a real CI/CD pipeline

For any team treating Batch like production infrastructure, the deployment pipeline matters more than the API knowledge. The minimal pipeline I deploy at every customer has four stages: infra plan (Bicep what-if or Terraform plan), infra apply (idempotent), app package upload (versioned), and smoke test (submit one canary task end to end).

# GitHub Actions snippet I reuse across customers
- name: Bicep what-if
  run: az deployment group what-if -g rg-batch-prod \
    --template-file ./infra/main.bicep \
    --parameters env=prod

- name: Bicep apply
  run: az deployment group create -g rg-batch-prod \
    --template-file ./infra/main.bicep \
    --parameters env=prod

- name: Upload app package
  run: az batch application package create \
    --resource-group rg-batch-prod \
    --name mybatchprod \
    --application-name renderer \
    --version $GITHUB_SHA \
    --package-file ./dist/renderer.zip

- name: Smoke task
  run: ./scripts/submit-canary.sh $GITHUB_SHA

The canary stage submits one task that runs end to end, pulls inputs, runs the workload for 30 seconds on toy data, writes a known output, exits. If the canary fails, the deploy is rolled back automatically. This single guard has caught more bad deploys for me than every unit test combined.

Security posture I never compromise

Three rules. No exceptions.

The third one feels paranoid until you actually need it. A Pune fintech I worked with had an incident where a pool node started exfiltrating data to an unknown IP. The start task log was the only artifact that survived node reimage and showed the exact moment the malicious payload landed. Without that log we would have been blind.

Closing thoughts from the field

Azure Batch is one of those services that looks simple at the API surface and quietly becomes complicated as soon as production traffic hits. The Learn page for Cross-region disaster recovery and business continuity covers the happy path. The real work is in the edges. quotas, IAM, networking, monitoring, cost, and security posture. Treat every Batch deployment like a small piece of infrastructure with its own ops runbook, and you will sleep better.

If you only take away three things from this guide: pin everything (versions, images, SKUs), monitor pool allocation state continuously, and keep your start task small and idempotent. Those three habits prevent about 80 percent of the incidents I have responded to in three years of running Batch for clients across India and Southeast Asia.

One last piece of unsolicited advice, write the runbook before you write the production code. A 200-word document that says "if this pool stops resizing, do X; if this account hits quota, do Y; if costs spike, look at Z" pays off the first time someone other than you is on call. I have been the someone-other-than-you many times. Be kind to that person.

Related guides worth a look while you sort this one out: