0
# Disaster Recovery
1
2
Geo-disaster recovery configuration, pairing management, failover operations, and data replication control. Service Bus Geo-disaster recovery provides automatic failover capability by pairing a primary namespace with a secondary namespace in different Azure regions.
3
4
## Capabilities
5
6
### Disaster Recovery Configuration Management
7
8
Create, retrieve, update, and delete geo-disaster recovery configurations for namespace pairing.
9
10
```python { .api }
11
def list(
12
self,
13
resource_group_name: str,
14
namespace_name: str
15
) -> ItemPaged[ArmDisasterRecovery]:
16
"""List disaster recovery configurations for a namespace.
17
18
Args:
19
resource_group_name (str): Name of the resource group.
20
namespace_name (str): Name of the primary namespace.
21
22
Returns:
23
ItemPaged[ArmDisasterRecovery]: Iterable of disaster recovery configurations.
24
"""
25
26
def create_or_update(
27
self,
28
resource_group_name: str,
29
namespace_name: str,
30
alias: str,
31
parameters: ArmDisasterRecovery
32
) -> ArmDisasterRecovery:
33
"""Create or update a disaster recovery configuration.
34
35
Args:
36
resource_group_name (str): Name of the resource group.
37
namespace_name (str): Name of the primary namespace.
38
alias (str): Name of the disaster recovery alias.
39
parameters (ArmDisasterRecovery): DR configuration parameters.
40
41
Returns:
42
ArmDisasterRecovery: The disaster recovery configuration.
43
"""
44
45
def get(
46
self,
47
resource_group_name: str,
48
namespace_name: str,
49
alias: str
50
) -> ArmDisasterRecovery:
51
"""Get disaster recovery configuration details.
52
53
Args:
54
resource_group_name (str): Name of the resource group.
55
namespace_name (str): Name of the primary namespace.
56
alias (str): Name of the disaster recovery alias.
57
58
Returns:
59
ArmDisasterRecovery: The disaster recovery configuration.
60
"""
61
62
def delete(
63
self,
64
resource_group_name: str,
65
namespace_name: str,
66
alias: str
67
) -> None:
68
"""Delete a disaster recovery configuration.
69
70
Args:
71
resource_group_name (str): Name of the resource group.
72
namespace_name (str): Name of the primary namespace.
73
alias (str): Name of the disaster recovery alias.
74
"""
75
```
76
77
### Disaster Recovery Operations
78
79
Control pairing relationships and perform failover operations between primary and secondary namespaces.
80
81
```python { .api }
82
def break_pairing(
83
self,
84
resource_group_name: str,
85
namespace_name: str,
86
alias: str
87
) -> None:
88
"""Break the pairing between primary and secondary namespaces.
89
90
Args:
91
resource_group_name (str): Name of the resource group.
92
namespace_name (str): Name of the primary namespace.
93
alias (str): Name of the disaster recovery alias.
94
"""
95
96
def fail_over(
97
self,
98
resource_group_name: str,
99
namespace_name: str,
100
alias: str
101
) -> None:
102
"""Initiate failover from primary to secondary namespace.
103
104
Args:
105
resource_group_name (str): Name of the resource group.
106
namespace_name (str): Name of the secondary namespace.
107
alias (str): Name of the disaster recovery alias.
108
109
Note:
110
This operation is called on the secondary namespace to promote it to primary.
111
"""
112
```
113
114
### Disaster Recovery Authorization Rules
115
116
Manage authorization rules for disaster recovery aliases that work across both namespaces.
117
118
```python { .api }
119
def list_authorization_rules(
120
self,
121
resource_group_name: str,
122
namespace_name: str,
123
alias: str
124
) -> ItemPaged[SBAuthorizationRule]:
125
"""List authorization rules for a disaster recovery configuration.
126
127
Args:
128
resource_group_name (str): Name of the resource group.
129
namespace_name (str): Name of the namespace.
130
alias (str): Name of the disaster recovery alias.
131
132
Returns:
133
ItemPaged[SBAuthorizationRule]: Iterable of authorization rules.
134
"""
135
136
def get_authorization_rule(
137
self,
138
resource_group_name: str,
139
namespace_name: str,
140
alias: str,
141
authorization_rule_name: str
142
) -> SBAuthorizationRule:
143
"""Get an authorization rule for a disaster recovery configuration.
144
145
Args:
146
resource_group_name (str): Name of the resource group.
147
namespace_name (str): Name of the namespace.
148
alias (str): Name of the disaster recovery alias.
149
authorization_rule_name (str): Name of the authorization rule.
150
151
Returns:
152
SBAuthorizationRule: The authorization rule.
153
"""
154
155
def list_keys(
156
self,
157
resource_group_name: str,
158
namespace_name: str,
159
alias: str,
160
authorization_rule_name: str
161
) -> AccessKeys:
162
"""Get access keys for a disaster recovery authorization rule.
163
164
Args:
165
resource_group_name (str): Name of the resource group.
166
namespace_name (str): Name of the namespace.
167
alias (str): Name of the disaster recovery alias.
168
authorization_rule_name (str): Name of the authorization rule.
169
170
Returns:
171
AccessKeys: Keys with alias connection strings for disaster recovery.
172
"""
173
```
174
175
## Usage Examples
176
177
### Setting Up Geo-Disaster Recovery
178
179
```python
180
from azure.mgmt.servicebus import ServiceBusManagementClient
181
from azure.mgmt.servicebus.models import ArmDisasterRecovery
182
from azure.identity import DefaultAzureCredential
183
184
client = ServiceBusManagementClient(DefaultAzureCredential(), subscription_id)
185
186
# First, create primary and secondary namespaces in different regions
187
# (This example assumes they already exist)
188
189
# Configure geo-disaster recovery pairing
190
dr_config = ArmDisasterRecovery(
191
partner_namespace="/subscriptions/{subscription-id}/resourceGroups/my-secondary-rg/providers/Microsoft.ServiceBus/namespaces/my-secondary-namespace",
192
alternate_name="my-dr-alias" # Optional friendly name
193
)
194
195
disaster_recovery = client.disaster_recovery_configs.create_or_update(
196
resource_group_name="my-primary-rg",
197
namespace_name="my-primary-namespace",
198
alias="my-dr-alias",
199
parameters=dr_config
200
)
201
202
print(f"Disaster recovery configured: {disaster_recovery.name}")
203
print(f"Partner namespace: {disaster_recovery.partner_namespace}")
204
print(f"Role: {disaster_recovery.role}")
205
print(f"Provisioning state: {disaster_recovery.provisioning_state}")
206
207
# Wait for the pairing to be established
208
import time
209
while True:
210
dr_status = client.disaster_recovery_configs.get(
211
resource_group_name="my-primary-rg",
212
namespace_name="my-primary-namespace",
213
alias="my-dr-alias"
214
)
215
216
if dr_status.provisioning_state == "Succeeded":
217
print("Disaster recovery pairing established successfully")
218
break
219
elif dr_status.provisioning_state == "Failed":
220
print("Disaster recovery pairing failed")
221
break
222
else:
223
print(f"Waiting for pairing... Status: {dr_status.provisioning_state}")
224
time.sleep(10)
225
```
226
227
### Using Disaster Recovery Alias Connection Strings
228
229
```python
230
# Get authorization rules for the disaster recovery alias
231
dr_auth_rules = client.disaster_recovery_configs.list_authorization_rules(
232
resource_group_name="my-primary-rg",
233
namespace_name="my-primary-namespace",
234
alias="my-dr-alias"
235
)
236
237
for rule in dr_auth_rules:
238
print(f"DR Auth Rule: {rule.name}")
239
print(f"Rights: {rule.rights}")
240
241
# Get access keys for disaster recovery
242
# These connection strings automatically point to the active namespace
243
dr_keys = client.disaster_recovery_configs.list_keys(
244
resource_group_name="my-primary-rg",
245
namespace_name="my-primary-namespace",
246
alias="my-dr-alias",
247
authorization_rule_name="RootManageSharedAccessKey"
248
)
249
250
print("Disaster Recovery Connection Strings:")
251
print(f"Primary: {dr_keys.alias_primary_connection_string}")
252
print(f"Secondary: {dr_keys.alias_secondary_connection_string}")
253
254
# Applications should use these alias connection strings
255
# They automatically redirect to the active namespace
256
connection_string = dr_keys.alias_primary_connection_string
257
```
258
259
### Monitoring Disaster Recovery Status
260
261
```python
262
from azure.mgmt.servicebus.models import RoleDisasterRecovery, ProvisioningStateDR
263
264
# Monitor disaster recovery configuration
265
dr_config = client.disaster_recovery_configs.get(
266
resource_group_name="my-primary-rg",
267
namespace_name="my-primary-namespace",
268
alias="my-dr-alias"
269
)
270
271
print(f"Disaster Recovery Status:")
272
print(f"Alias: {dr_config.name}")
273
print(f"Role: {dr_config.role}")
274
print(f"Provisioning State: {dr_config.provisioning_state}")
275
print(f"Partner Namespace: {dr_config.partner_namespace}")
276
print(f"Alternate Name: {dr_config.alternate_name}")
277
print(f"Pending Replication Operations: {dr_config.pending_replication_operations_count}")
278
279
# Check the role to understand the current active namespace
280
if dr_config.role == RoleDisasterRecovery.PRIMARY:
281
print("This namespace is currently the PRIMARY (active)")
282
elif dr_config.role == RoleDisasterRecovery.SECONDARY:
283
print("This namespace is currently the SECONDARY (standby)")
284
elif dr_config.role == RoleDisasterRecovery.PRIMARY_NOT_REPLICATING:
285
print("This namespace is PRIMARY but not replicating (pairing broken)")
286
287
# Monitor replication status
288
if dr_config.pending_replication_operations_count > 0:
289
print(f"Warning: {dr_config.pending_replication_operations_count} operations pending replication")
290
```
291
292
### Performing Planned Failover
293
294
```python
295
# Before failover, check the current status
296
primary_dr = client.disaster_recovery_configs.get(
297
resource_group_name="my-primary-rg",
298
namespace_name="my-primary-namespace",
299
alias="my-dr-alias"
300
)
301
302
print(f"Before failover - Primary role: {primary_dr.role}")
303
304
# Initiate failover from the secondary namespace
305
# Note: This promotes the secondary to become the new primary
306
try:
307
client.disaster_recovery_configs.fail_over(
308
resource_group_name="my-secondary-rg",
309
namespace_name="my-secondary-namespace",
310
alias="my-dr-alias"
311
)
312
313
print("Failover initiated successfully")
314
315
# Wait for failover to complete
316
time.sleep(30)
317
318
# Check the new status
319
secondary_dr = client.disaster_recovery_configs.get(
320
resource_group_name="my-secondary-rg",
321
namespace_name="my-secondary-namespace",
322
alias="my-dr-alias"
323
)
324
325
print(f"After failover - Secondary role: {secondary_dr.role}")
326
327
except Exception as e:
328
print(f"Failover failed: {e}")
329
```
330
331
### Breaking Disaster Recovery Pairing
332
333
```python
334
# Break the pairing when DR is no longer needed
335
# This should be done from the primary namespace
336
try:
337
client.disaster_recovery_configs.break_pairing(
338
resource_group_name="my-primary-rg",
339
namespace_name="my-primary-namespace",
340
alias="my-dr-alias"
341
)
342
343
print("Disaster recovery pairing broken successfully")
344
345
# After breaking, both namespaces become independent
346
# The alias connection strings will no longer work
347
348
except Exception as e:
349
print(f"Failed to break pairing: {e}")
350
351
# Clean up the disaster recovery configuration
352
client.disaster_recovery_configs.delete(
353
resource_group_name="my-primary-rg",
354
namespace_name="my-primary-namespace",
355
alias="my-dr-alias"
356
)
357
358
print("Disaster recovery configuration deleted")
359
```
360
361
### Disaster Recovery Best Practices Implementation
362
363
```python
364
def setup_disaster_recovery_with_monitoring():
365
"""Complete disaster recovery setup with monitoring"""
366
367
# 1. Create the DR pairing
368
dr_config = ArmDisasterRecovery(
369
partner_namespace="/subscriptions/{subscription-id}/resourceGroups/secondary-rg/providers/Microsoft.ServiceBus/namespaces/secondary-namespace"
370
)
371
372
dr = client.disaster_recovery_configs.create_or_update(
373
resource_group_name="primary-rg",
374
namespace_name="primary-namespace",
375
alias="production-dr",
376
parameters=dr_config
377
)
378
379
# 2. Wait for pairing to complete
380
max_wait_time = 300 # 5 minutes
381
wait_interval = 10 # 10 seconds
382
elapsed_time = 0
383
384
while elapsed_time < max_wait_time:
385
status = client.disaster_recovery_configs.get(
386
resource_group_name="primary-rg",
387
namespace_name="primary-namespace",
388
alias="production-dr"
389
)
390
391
if status.provisioning_state == "Succeeded":
392
print("Disaster recovery pairing established")
393
break
394
elif status.provisioning_state == "Failed":
395
raise Exception("Disaster recovery pairing failed")
396
397
time.sleep(wait_interval)
398
elapsed_time += wait_interval
399
400
# 3. Get DR connection strings for applications
401
dr_keys = client.disaster_recovery_configs.list_keys(
402
resource_group_name="primary-rg",
403
namespace_name="primary-namespace",
404
alias="production-dr",
405
authorization_rule_name="RootManageSharedAccessKey"
406
)
407
408
# 4. Store connection strings securely (e.g., Azure Key Vault)
409
dr_connection_string = dr_keys.alias_primary_connection_string
410
411
return {
412
"dr_alias": "production-dr",
413
"connection_string": dr_connection_string,
414
"status": "active"
415
}
416
417
def check_disaster_recovery_health():
418
"""Monitor disaster recovery health"""
419
420
dr_status = client.disaster_recovery_configs.get(
421
resource_group_name="primary-rg",
422
namespace_name="primary-namespace",
423
alias="production-dr"
424
)
425
426
health_check = {
427
"alias": dr_status.name,
428
"role": dr_status.role,
429
"provisioning_state": dr_status.provisioning_state,
430
"pending_operations": dr_status.pending_replication_operations_count,
431
"healthy": True,
432
"issues": []
433
}
434
435
# Check for issues
436
if dr_status.provisioning_state != "Succeeded":
437
health_check["healthy"] = False
438
health_check["issues"].append(f"Provisioning state: {dr_status.provisioning_state}")
439
440
if dr_status.pending_replication_operations_count > 10:
441
health_check["healthy"] = False
442
health_check["issues"].append(f"High pending operations: {dr_status.pending_replication_operations_count}")
443
444
if dr_status.role == RoleDisasterRecovery.PRIMARY_NOT_REPLICATING:
445
health_check["healthy"] = False
446
health_check["issues"].append("Primary not replicating - pairing may be broken")
447
448
return health_check
449
450
# Example usage
451
try:
452
dr_info = setup_disaster_recovery_with_monitoring()
453
print(f"DR setup complete: {dr_info}")
454
455
# Periodic health checks
456
health = check_disaster_recovery_health()
457
if not health["healthy"]:
458
print(f"DR Health Issues: {health['issues']}")
459
else:
460
print("Disaster recovery is healthy")
461
462
except Exception as e:
463
print(f"Disaster recovery setup failed: {e}")
464
```
465
466
## Types
467
468
```python { .api }
469
class ArmDisasterRecovery:
470
def __init__(self, **kwargs): ...
471
472
# Disaster recovery properties
473
id: Optional[str]
474
name: Optional[str]
475
type: Optional[str]
476
477
# Configuration
478
provisioning_state: Optional[Union[str, ProvisioningStateDR]]
479
pending_replication_operations_count: Optional[int]
480
partner_namespace: Optional[str] # ARM resource ID of partner namespace
481
alternate_name: Optional[str] # Friendly name for the alias
482
role: Optional[Union[str, RoleDisasterRecovery]]
483
484
class ArmDisasterRecoveryListResult:
485
def __init__(self, **kwargs): ...
486
487
value: Optional[List[ArmDisasterRecovery]]
488
next_link: Optional[str]
489
490
from enum import Enum
491
492
class ProvisioningStateDR(str, Enum):
493
ACCEPTED = "Accepted"
494
SUCCEEDED = "Succeeded"
495
FAILED = "Failed"
496
497
class RoleDisasterRecovery(str, Enum):
498
PRIMARY = "Primary" # Active namespace receiving traffic
499
PRIMARY_NOT_REPLICATING = "PrimaryNotReplicating" # Primary but pairing broken
500
SECONDARY = "Secondary" # Standby namespace receiving replication
501
```
502
503
## Disaster Recovery Architecture
504
505
### Pairing Relationship
506
- **Primary Namespace**: Active namespace that receives all traffic
507
- **Secondary Namespace**: Standby namespace in different region that receives metadata replication
508
- **Alias**: DNS name that automatically points to the active namespace
509
510
### Failover Process
511
1. **Automatic Metadata Replication**: Entity configurations are replicated from primary to secondary
512
2. **Message Data**: Messages are not replicated (they remain in the original namespace)
513
3. **Failover**: Promotes secondary namespace to primary role
514
4. **DNS Update**: Alias automatically redirects to the new primary namespace
515
516
### Best Practices
517
- Use different Azure regions for primary and secondary namespaces
518
- Monitor replication lag using `pending_replication_operations_count`
519
- Use alias connection strings in applications for automatic failover
520
- Test failover procedures regularly in non-production environments
521
- Consider message data loss implications when planning failover strategies
522
- Break pairing only when disaster recovery is no longer needed