Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/dataprotection/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

1.12.0
++++++
* Added dataprotection support for the AzureElasticSAN (Elastic SAN volume group) workload: new manifest (Microsoft.ElasticSan/elasticSans/volumeGroups), registration in supported datasource types and datasource map. New backup configuration via ``az dataprotection backup-instance initialize-backupconfig --datasource-type AzureElasticSAN --resource-selectors`` (GenericBackupDatasourceParameters) and restore configuration via ``az dataprotection backup-instance initialize-restoreconfig --datasource-type AzureElasticSAN --resource-identifiers/--resource-name-overrides`` (GenericRestoreDatasourceCriteria), with data-recovery and item-recovery restore wiring plus help/examples. The AzureElasticSAN backup-instance operations are pinned to the GA 2026-06-01 DataProtection API, which defines GenericBackupDatasourceParameters/GenericRestoreDatasourceCriteria natively.

1.11.3
++++++++++++++++
* [Breaking] `az dataprotection backup-policy retention-rule set` validates against duplicate retention-rule names. AzureBlob: OperationalStore retention lifecycles must now use the retention rule name `--name Default_OperationalStore`. Using `--name Default` with an OperationalStore lifecycle for AzureBlobis no longer accepted.
Expand Down
84 changes: 84 additions & 0 deletions src/dataprotection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,90 @@ az dataprotection backup-instance validate-for-restore --name "testInstance1" --
az dataprotection backup-instance restore trigger -g sarath-rg --vault-name sarath-vault \
--backup-instance-name {backup_instance_name} --restore=request-object restore_request.json
```

#### Azure Elastic SAN (preview) configure and restore scripts ####
##### Configure backup for Elastic SAN volumes #####
```
# 1) Create backup configuration for selected source volumes in the chosen volume group
az dataprotection backup-instance initialize-backupconfig \
--datasource-type AzureElasticSAN \
--resource-selectors volume001 volume002 > esan_backup_config.json
Comment thread
priyansh17 marked this conversation as resolved.
Outdated

# 2) Initialize backup instance payload (datasource-id is the source volume group ARM ID)
az dataprotection backup-instance initialize \
--datasource-type AzureElasticSAN \
--datasource-location {location} \
--datasource-id {source_volume_group_id} \
--policy-id {esan_policy_id} \
--friendly-name esan-bi \
--backup-configuration @esan_backup_config.json > esan_backup_instance.json

# 3) Grant missing backup permissions to vault MSI (Elastic SAN Snapshot Exporter + Disk Snapshot Contributor)
az dataprotection backup-instance update-msi-permissions \
--datasource-type AzureElasticSAN \
--operation Backup \
--permissions-scope Resource \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json

# 4) Validate and configure backup
az dataprotection backup-instance validate-for-backup \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json

az dataprotection backup-instance create \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance @esan_backup_instance.json
```

##### Restore Elastic SAN backup #####
```
# 1) Build restore configuration: select source volumes and optional target names
az dataprotection backup-instance initialize-restoreconfig \
--datasource-type AzureElasticSAN \
--resource-identifiers source-vol1 source-vol2 \
--resource-name-overrides '{"source-vol1":"restored-vol1","source-vol2":"restored-vol2"}' > esan_restore_config.json

# 2) Initialize restore request (target-resource-id is target volume group ARM ID).
# Elastic SAN supports alternate-location restore only, so pass --target-resource-id
# (do not pass --backup-instance-id; the two are mutually exclusive).
az dataprotection backup-instance restore initialize-for-item-recovery \
--datasource-type AzureElasticSAN \
--source-datastore OperationalStore \
--restore-location {location} \
--recovery-point-id {recovery_point_id} \
--target-resource-id {target_volume_group_id} \
--restore-configuration @esan_restore_config.json > esan_restore_request.json

# 3) Grant missing restore permissions to vault MSI
# - Elastic SAN Volume Importer on target Elastic SAN
# - Reader on snapshot resource group (pass --snapshot-resource-group-id)
az dataprotection backup-instance update-msi-permissions \
--datasource-type AzureElasticSAN \
--operation Restore \
--permissions-scope Resource \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--restore-request-object @esan_restore_request.json \
--snapshot-resource-group-id {snapshot_rg_id}

# 4) Validate and trigger restore
az dataprotection backup-instance validate-for-restore \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance-name {backup_instance_name} \
--restore-request-object @esan_restore_request.json

az dataprotection backup-instance restore trigger \
--resource-group {vault_rg} \
--vault-name {vault_name} \
--backup-instance-name {backup_instance_name} \
--restore-request-object @esan_restore_request.json
```

#### dataprotection backup-vault ####
##### Create #####
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down Expand Up @@ -481,6 +481,15 @@ def _build_schema_on_200_201(cls):
)
_CreateHelper._build_schema_blob_backup_rule_based_auto_protection_settings_read(disc_blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings)

disc_generic_backup_datasource_parameters = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters")
disc_generic_backup_datasource_parameters.resource_selectors = AAZListType(
serialized_name="resourceSelectors",
flags={"required": True},
)

resource_selectors = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters").resource_selectors
resource_selectors.Element = AAZStrType()

disc_kubernetes_cluster_backup_datasource_parameters = cls._schema_on_200_201.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "KubernetesClusterBackupDatasourceParameters")
disc_kubernetes_cluster_backup_datasource_parameters.backup_hook_references = AAZListType(
serialized_name="backupHookReferences",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down Expand Up @@ -1213,6 +1213,15 @@ def _build_schema_backup_instance_resource_read(cls, _schema):
)
cls._build_schema_blob_backup_rule_based_auto_protection_settings_read(disc_blob_backup_datasource_parameters_for_auto_protection.auto_protection_settings)

disc_generic_backup_datasource_parameters = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters")
disc_generic_backup_datasource_parameters.resource_selectors = AAZListType(
serialized_name="resourceSelectors",
flags={"required": True},
)

resource_selectors = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "GenericBackupDatasourceParameters").resource_selectors
resource_selectors.Element = AAZStrType()

disc_kubernetes_cluster_backup_datasource_parameters = _schema_backup_instance_resource_read.properties.policy_info.policy_parameters.backup_datasource_parameters_list.Element.discriminate_by("object_type", "KubernetesClusterBackupDatasourceParameters")
disc_kubernetes_cluster_backup_datasource_parameters.backup_hook_references = AAZListType(
serialized_name="backupHookReferences",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2026-03-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2025-07-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2025-07-01",
"api-version", "2026-06-01",
required=True,
),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

manifest = '''
{
"isProxyResource": true,
"enableDataSourceSetInfo": true,
"resourceType": "Microsoft.ElasticSan/elasticSans/volumeGroups",
"parentResourceType": "Microsoft.ElasticSan/elasticSans",
"datasourceType": "Microsoft.ElasticSan/elasticSans/volumeGroups",
"allowedRestoreModes": [ "RecoveryPointBased" ],
"allowedRestoreTargetTypes": [ "AlternateLocation" ],
"itemLevelRecoveryEnabled": true,
"addBackupDatasourceParametersList": true,
"backupConfigurationRequired": true,
"addDataStoreParametersList": true,
"friendlyNameRequired": true,
"supportSecretStoreAuthentication": false,
"backupVaultPermissions": [
{
"roleDefinitionName": "Elastic SAN Snapshot Exporter",
"type": "DataSource"
},
{
"roleDefinitionName": "Disk Snapshot Contributor",
"type": "SnapshotRG"
}
],
"backupVaultRestorePermissions": [
{
"roleDefinitionName": "Elastic SAN Volume Importer",
"type": "DataSource"
},
{
"roleDefinitionName": "Reader",
"type": "SnapshotRG"
}
],
"policySettings": {
"supportedRetentionTags": [ "Daily", "Weekly" ],
"supportedDatastoreTypes": [ "OperationalStore" ],
"disableAddRetentionRule": false,
"disableCustomRetentionTag": true,
"backupScheduleSupported": true,
"supportedBackupFrequency": [ "Daily", "Weekly" ],
"defaultPolicy": {
"policyRules": [
{
"backupParameters": {
"backupType": "Incremental",
"objectType": "AzureBackupParams"
},
"trigger": {
"schedule": {
"repeatingTimeIntervals": [
"R/2024-02-08T13:00:00+00:00/P1D"
]
},
"taggingCriteria": [
{
"tagInfo": {
"tagName": "Default",
"id": "Default_"
},
"taggingPriority": 99,
"isDefault": true
}
],
"objectType": "ScheduleBasedTriggerContext"
},
"dataStore": {
"dataStoreType": "OperationalStore",
"objectType": "DataStoreInfoBase"
},
"name": "BackupDaily",
"objectType": "AzureBackupRule"
},
{
"lifecycles": [
{
"deleteAfter": {
"objectType": "AbsoluteDeleteOption",
"duration": "P7D"
},
"sourceDataStore": {
"dataStoreType": "OperationalStore",
"objectType": "DataStoreInfoBase"
}
}
],
"isDefault": true,
"name": "Default",
"objectType": "AzureRetentionRule"
}
],
"name": "ESANPolicy1",
"datasourceTypes": [
"Microsoft.ElasticSan/elasticSans/volumeGroups"
],
"objectType": "BackupPolicy"
}
}
}
'''
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
supported_datasource_types = ["AzureDisk", "AzureBlob", "AzureDataLakeStorage",
"AzureDatabaseForPostgreSQL", "AzureKubernetesService",
"AzureDatabaseForPostgreSQLFlexibleServer", "AzureDatabaseForMySQL",
"AzureCosmosDB"]
"AzureCosmosDB", "AzureElasticSAN"]
Loading