Skip to content

Commit 3b725b4

Browse files
authored
Cross subscription storage account support for workspace (Azure#37288)
* fixing sweep job service response parsing issue * fixing sweep job service response parsing issue * raising a work around for cmd job and spark job name lowering case * fixing black issue * fixing serialization issue in sweep job * include black fix * found and fix the issue in compute validation * fixing a corrupt wokspace arm template * fixing the failed test case * updating the date for 1.18.0 release * removing empty section * adding in progress version details * adding IDC code reviewers * correcting the directory path * lint fix * adding change log entry * addressing review comment * fixing ut * addressing api review comment * adding a fix for subnet validation in compute instance * my py fix * fixing autoML serialization issue * formatting * moving auto ML job create API to 2024 * subscription spell correction * adding change log entry * fixing UT * fix default workspace creation
1 parent bddc491 commit 3b725b4

File tree

6 files changed

+33
-3
lines changed

6 files changed

+33
-3
lines changed

sdk/ml/azure-ai-ml/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## 1.21.0 (unreleased)
44

5+
### Features Added
6+
- Cross subscription storage account support for workspace and feature store. Developer can provide a storage account from another subscription while creating a workspace or storage account.
7+
58
## 1.20.0 (2024-09-10)
69

710
### Features Added

sdk/ml/azure-ai-ml/azure/ai/ml/_arm_deployments/arm_templates/workspace_base.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@
8383
"description": "Determines whether or not to put the storage account behind VNet"
8484
}
8585
},
86+
"storageAccountSubscriptionId": {
87+
"type": "string",
88+
"defaultValue": "[subscription().subscriptionId]"
89+
},
8690
"storageAccountResourceGroupName": {
8791
"type": "string",
8892
"defaultValue": "[parameters('resourceGroupName')]"
@@ -635,7 +639,7 @@
635639
},
636640
"variables": {
637641
"tenantId": "[subscription().tenantId]",
638-
"storageAccount": "[resourceId(parameters('storageAccountResourceGroupName'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
642+
"storageAccount": "[resourceId(parameters('storageAccountSubscriptionId'), parameters('storageAccountResourceGroupName'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
639643
"keyVault": "[resourceId(parameters('keyVaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]",
640644
"containerRegistry": "[resourceId(parameters('containerRegistryResourceGroupName'), 'Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]",
641645
"applicationInsights": "[resourceId(parameters('applicationInsightsResourceGroupName'), 'Microsoft.Insights/components', parameters('applicationInsightsName'))]",

sdk/ml/azure-ai-ml/azure/ai/ml/_arm_deployments/arm_templates/workspace_param.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
"storageAccountName": {
3939
"value": ""
4040
},
41+
"storageAccountSubscriptionId": {
42+
"value": ""
43+
},
4144
"storageAccountResourceGroupName": {
4245
"value": ""
4346
},

sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_workspace_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ def get_resource_and_group_name(armstr: str) -> str:
8484
return armstr.split("/")[-1], armstr.split("/")[-5]
8585

8686

87+
def get_sub_id_resource_and_group_name(armstr: str) -> str:
88+
return armstr.split("/")[-7], armstr.split("/")[-1], armstr.split("/")[-5]
89+
90+
8791
def get_endpoint_parts(arm_id: str, subnet_arm_id: str) -> ():
8892
arm_id_parts = arm_id.split("/")
8993
subnet_id_parts = subnet_arm_id.split("/")

sdk/ml/azure-ai-ml/azure/ai/ml/operations/_workspace_operations_base.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,17 @@
2929
get_name_for_dependent_resource,
3030
get_resource_and_group_name,
3131
get_resource_group_location,
32+
get_sub_id_resource_and_group_name,
3233
)
3334
from azure.ai.ml._utils.utils import camel_to_snake, from_iso_duration_format_min_sec
3435
from azure.ai.ml._version import VERSION
3536
from azure.ai.ml.constants import ManagedServiceIdentityType
3637
from azure.ai.ml.constants._common import (
38+
WORKSPACE_PATCH_REJECTED_KEYS,
3739
ArmConstants,
3840
LROConfigurations,
3941
WorkspaceKind,
4042
WorkspaceResourceConstants,
41-
WORKSPACE_PATCH_REJECTED_KEYS,
4243
)
4344
from azure.ai.ml.constants._workspace import IsolationMode, OutboundRuleCategory
4445
from azure.ai.ml.entities import Hub, Project, Workspace
@@ -582,17 +583,22 @@ def _populate_arm_parameters(self, workspace: Workspace, **kwargs: Any) -> Tuple
582583
)
583584

584585
if workspace.storage_account:
585-
resource_name, group_name = get_resource_and_group_name(workspace.storage_account)
586+
subscription_id, resource_name, group_name = get_sub_id_resource_and_group_name(workspace.storage_account)
586587
_set_val(param["storageAccountName"], resource_name)
587588
_set_val(param["storageAccountOption"], "existing")
588589
_set_val(param["storageAccountResourceGroupName"], group_name)
590+
_set_val(param["storageAccountSubscriptionId"], subscription_id)
589591
else:
590592
storage = _generate_storage(workspace.name, resources_being_deployed)
591593
_set_val(param["storageAccountName"], storage)
592594
_set_val(
593595
param["storageAccountResourceGroupName"],
594596
workspace.resource_group,
595597
)
598+
_set_val(
599+
param["storageAccountSubscriptionId"],
600+
self._subscription_id,
601+
)
596602

597603
if workspace.application_insights:
598604
resource_name, group_name = get_resource_and_group_name(workspace.application_insights)

sdk/ml/azure-ai-ml/tests/workspace/unittests/test_workspace_operations_base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from azure.ai.ml._restclient.v2024_07_01_preview.models import (
99
EncryptionKeyVaultUpdateProperties,
1010
EncryptionUpdateProperties,
11+
)
12+
from azure.ai.ml._restclient.v2024_07_01_preview.models import (
1113
ServerlessComputeSettings as RestServerlessComputeSettings,
1214
)
1315
from azure.ai.ml._scope_dependent_operations import OperationScope
@@ -305,6 +307,10 @@ def _populate_arm_parameters(
305307
def test_populate_arm_parameters_other_branches(
306308
self, mock_workspace_operation_base: WorkspaceOperationsBase, mocker: MockFixture
307309
) -> None:
310+
mocker.patch(
311+
"azure.ai.ml.operations._workspace_operations_base.get_sub_id_resource_and_group_name",
312+
return_value=["random_name", "random_grp", "random_storage"],
313+
)
308314
mocker.patch(
309315
"azure.ai.ml.operations._workspace_operations_base.get_resource_group_location", return_value="random_name"
310316
)
@@ -330,6 +336,10 @@ def test_populate_arm_parameters_other_branches(
330336
def test_populate_feature_store_arm_parameters(
331337
self, mock_workspace_operation_base: WorkspaceOperationsBase, mocker: MockFixture
332338
) -> None:
339+
mocker.patch(
340+
"azure.ai.ml.operations._workspace_operations_base.get_sub_id_resource_and_group_name",
341+
return_value=["random_sub", "random_grp", "random_storage"],
342+
)
333343
mocker.patch(
334344
"azure.ai.ml.operations._workspace_operations_base.get_resource_group_location", return_value="random_name"
335345
)

0 commit comments

Comments
 (0)