or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authorization-security.mddisaster-recovery.mdindex.mdmessage-filtering-rules.mdmigration-monitoring.mdnamespace-management.mdqueue-operations.mdtopic-subscription-management.md

disaster-recovery.mddocs/

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