├── .gitignore ├── LICENSE ├── README.md ├── arm ├── parameters.json └── template.json ├── cli ├── cli-demo.png ├── instructions.md └── script.sh ├── portal ├── instructions.md └── portal-demo.png └── sdk ├── .env.example ├── connect_to_workspace.py ├── create_workspace.py ├── instructions.md └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 OscarSantosMu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Machine Learning Workspace Creation 2 | 3 | This repository demonstrates four different methods to create an Azure Machine Learning workspace: 4 | 5 | 1. **Azure Portal**: This method involves using the Azure Portal web interface to create a new Azure Machine Learning workspace. Detailed step-by-step instructions are provided in the [Azure Portal Method](./portal/instructions.md) guide. 6 | 7 | 2. **Azure CLI**: The Azure Command-Line Interface (CLI) allows you to create an Azure Machine Learning workspace using command-line commands. Refer to the [Azure CLI Method](./cli/instructions.md) guide for detailed instructions. 8 | 9 | 3. **Azure Python SDK**: The Azure Python SDK provides a powerful way to programmatically create an Azure Machine Learning workspace using Python code. Check out the [Azure Python SDK Method](./sdk/instructions.md) guide for code examples and instructions. 10 | 11 | 4. **ARM Templates**: Azure Resource Manager (ARM) templates enable you to define and deploy Azure resources, including an Azure Machine Learning workspace, using declarative JSON templates. The [ARM template](./arm/template.json) is shown only as an example but it is possible to create a workspace from it. [Here is how you could do it](https://learn.microsoft.com/azure/azure-resource-manager/templates/template-tutorial-create-first-template?tabs=azure-cli&WT.mc_id=MVP_340422#create-your-first-template). 12 | 13 | Choose the method that suits your needs and follow the respective guide to create your Azure Machine Learning workspace. 14 | 15 | ## Prerequisites 16 | 17 | Before you begin, make sure you have the following prerequisites: 18 | 19 | - An Azure subscription 20 | - Access to the Azure Portal, Azure CLI, or Azure Python SDK, depending on the method you choose 21 | 22 | ## Contributing 23 | 24 | If you would like to contribute to this repository, please make a Pull Request. 25 | -------------------------------------------------------------------------------- /arm/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "workspaceName": { 6 | "value": "mlw-dp100-arm" 7 | }, 8 | "description": { 9 | "value": "This example shows how to create a basic workspace" 10 | }, 11 | "friendlyName": { 12 | "value": "Basic workspace-example" 13 | }, 14 | "kind": { 15 | "value": "default" 16 | }, 17 | "location": { 18 | "value": "eastus" 19 | }, 20 | "resourceGroupName": { 21 | "value": "bootcamp-dp100" 22 | }, 23 | "storageAccountOption": { 24 | "value": "new" 25 | }, 26 | "storageAccountName": { 27 | "value": "mlwdp100storagef05d3b9d2" 28 | }, 29 | "storageAccountType": { 30 | "value": "Standard_LRS" 31 | }, 32 | "storageAccountBehindVNet": { 33 | "value": "false" 34 | }, 35 | "storageAccountResourceGroupName": { 36 | "value": "bootcamp-dp100" 37 | }, 38 | "storageAccountLocation": { 39 | "value": "eastus" 40 | }, 41 | "keyVaultOption": { 42 | "value": "new" 43 | }, 44 | "keyVaultName": { 45 | "value": "mlwdp100keyvault6d32854a" 46 | }, 47 | "keyVaultBehindVNet": { 48 | "value": "false" 49 | }, 50 | "keyVaultResourceGroupName": { 51 | "value": "bootcamp-dp100" 52 | }, 53 | "keyVaultLocation": { 54 | "value": "eastus" 55 | }, 56 | "applicationInsightsOption": { 57 | "value": "new" 58 | }, 59 | "logAnalyticsName": { 60 | "value": "mlwdp100logalyti4a3c87da" 61 | }, 62 | "logAnalyticsArmId": { 63 | "value": "/subscriptions/3bb6.......446e/resourceGroups/bootcamp-dp100/providers/Microsoft.OperationalInsights/workspaces/mlwdp100logalyti4a3c87da" 64 | }, 65 | "applicationInsightsName": { 66 | "value": "mlwdp100insightsf9ca52b6" 67 | }, 68 | "applicationInsightsResourceGroupName": { 69 | "value": "bootcamp-dp100" 70 | }, 71 | "applicationInsightsLocation": { 72 | "value": "eastus" 73 | }, 74 | "containerRegistryOption": { 75 | "value": "none" 76 | }, 77 | "containerRegistryName": { 78 | "value": "name" 79 | }, 80 | "containerRegistrySku": { 81 | "value": "Standard" 82 | }, 83 | "containerRegistryResourceGroupName": { 84 | "value": "" 85 | }, 86 | "containerRegistryBehindVNet": { 87 | "value": "false" 88 | }, 89 | "containerRegistryLocation": { 90 | "value": "eastus" 91 | }, 92 | "vnetOption": { 93 | "value": "existing" 94 | }, 95 | "vnetName": { 96 | "value": "name" 97 | }, 98 | "vnetResourceGroupName": { 99 | "value": "name" 100 | }, 101 | "addressPrefixes": { 102 | "value": [ 103 | "10.0.0.0/16" 104 | ] 105 | }, 106 | "subnetOption": { 107 | "value": "existing" 108 | }, 109 | "subnetName": { 110 | "value": "default" 111 | }, 112 | "subnetPrefix": { 113 | "value": "10.0.0.0/24" 114 | }, 115 | "adbWorkspace": { 116 | "value": "" 117 | }, 118 | "confidential_data": { 119 | "value": "false" 120 | }, 121 | "encryption_status": { 122 | "value": "Disabled" 123 | }, 124 | "cmk_keyvault": { 125 | "value": "" 126 | }, 127 | "resource_cmk_uri": { 128 | "value": "" 129 | }, 130 | "privateEndpointType": { 131 | "value": "none" 132 | }, 133 | "tagValues": { 134 | "value": { 135 | "createdByToolkit": "sdk-v2-1.15.0" 136 | } 137 | }, 138 | "privateEndpointName": { 139 | "value": "name" 140 | }, 141 | "privateEndpointResourceGroupName": { 142 | "value": "name" 143 | }, 144 | "imageBuildCompute": { 145 | "value": "" 146 | }, 147 | "publicNetworkAccess": { 148 | "value": "Enabled" 149 | }, 150 | "soft_delete_enabled": { 151 | "value": "false" 152 | }, 153 | "allow_recover_softdeleted_workspace": { 154 | "value": "false" 155 | }, 156 | "encryption_cosmosdb_resourceid": { 157 | "value": "" 158 | }, 159 | "encryption_storage_resourceid": { 160 | "value": "" 161 | }, 162 | "encryption_search_resourceid": { 163 | "value": "" 164 | }, 165 | "identity": { 166 | "value": { 167 | "type": "SystemAssigned" 168 | } 169 | }, 170 | "primaryUserAssignedIdentity": { 171 | "value": "" 172 | }, 173 | "managedNetwork": { 174 | "value": { 175 | "isolationMode": "Disabled", 176 | "outboundRules": {} 177 | } 178 | }, 179 | "spark_runtime_version": { 180 | "value": "" 181 | }, 182 | "offlineStoreStorageAccountOption": { 183 | "value": "none" 184 | }, 185 | "offline_store_storage_account_name": { 186 | "value": "sa4ldtsj6sckrty" 187 | }, 188 | "offline_store_container_name": { 189 | "value": "offlinestoreda0c3867-2981-4a56-a156-b7777be19905" 190 | }, 191 | "offline_store_resource_group_name": { 192 | "value": "bootcamp-dp100" 193 | }, 194 | "offline_store_subscription_id": { 195 | "value": "3bb6.......446e" 196 | }, 197 | "offline_store_connection_name": { 198 | "value": "" 199 | }, 200 | "online_store_resource_id": { 201 | "value": "" 202 | }, 203 | "online_store_resource_group_name": { 204 | "value": "" 205 | }, 206 | "online_store_subscription_id": { 207 | "value": "" 208 | }, 209 | "online_store_connection_name": { 210 | "value": "" 211 | }, 212 | "materializationIdentityOption": { 213 | "value": "none" 214 | }, 215 | "materialization_identity_name": { 216 | "value": "empty" 217 | }, 218 | "materialization_identity_subscription_id": { 219 | "value": "3bb6.......446e" 220 | }, 221 | "materialization_identity_resource_group_name": { 222 | "value": "bootcamp-dp100" 223 | }, 224 | "grant_materialization_permissions": { 225 | "value": "true" 226 | }, 227 | "enable_data_isolation": { 228 | "value": "false" 229 | }, 230 | "workspace_hub_config": { 231 | "value": {} 232 | }, 233 | "existing_workspaces": { 234 | "value": [] 235 | }, 236 | "workspace_hub": { 237 | "value": "" 238 | }, 239 | "serverless_compute_settings": { 240 | "value": {} 241 | }, 242 | "endpoint_resource_id": { 243 | "value": "null" 244 | }, 245 | "endpoint_kind": { 246 | "value": "AIServices" 247 | }, 248 | "endpoint_option": { 249 | "value": "new" 250 | } 251 | } 252 | } -------------------------------------------------------------------------------- /arm/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "workspaceName": { 6 | "type": "String", 7 | "metadata": { 8 | "description": "Specifies the name of the Azure Machine Learning workspace." 9 | } 10 | }, 11 | "description": { 12 | "type": "String", 13 | "metadata": { 14 | "description": "Description string." 15 | } 16 | }, 17 | "friendlyName": { 18 | "type": "String", 19 | "metadata": { 20 | "description": "Friendly name." 21 | } 22 | }, 23 | "kind": { 24 | "defaultValue": "Default", 25 | "type": "String", 26 | "metadata": { 27 | "description": "Specifies the Kind of the workspace." 28 | } 29 | }, 30 | "location": { 31 | "type": "String", 32 | "metadata": { 33 | "description": "Specifies the location for all resources." 34 | } 35 | }, 36 | "resourceGroupName": { 37 | "type": "String", 38 | "metadata": { 39 | "description": "Specifies the resource group name of the Azure Machine Learning workspace." 40 | } 41 | }, 42 | "storageAccountOption": { 43 | "defaultValue": "new", 44 | "allowedValues": [ 45 | "new", 46 | "existing" 47 | ], 48 | "type": "String", 49 | "metadata": { 50 | "description": "Determines whether or not a new storage should be provisioned." 51 | } 52 | }, 53 | "storageAccountName": { 54 | "defaultValue": "[concat('sa', uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 55 | "type": "String", 56 | "metadata": { 57 | "description": "Name of the storage account." 58 | } 59 | }, 60 | "storageAccountType": { 61 | "defaultValue": "Standard_LRS", 62 | "type": "String" 63 | }, 64 | "storageAccountBehindVNet": { 65 | "defaultValue": "false", 66 | "allowedValues": [ 67 | "true", 68 | "false" 69 | ], 70 | "type": "String", 71 | "metadata": { 72 | "description": "Determines whether or not to put the storage account behind VNet" 73 | } 74 | }, 75 | "storageAccountResourceGroupName": { 76 | "defaultValue": "[parameters('resourceGroupName')]", 77 | "type": "String" 78 | }, 79 | "storageAccountLocation": { 80 | "defaultValue": "[parameters('location')]", 81 | "type": "String" 82 | }, 83 | "keyVaultOption": { 84 | "defaultValue": "new", 85 | "allowedValues": [ 86 | "new", 87 | "existing" 88 | ], 89 | "type": "String", 90 | "metadata": { 91 | "description": "Determines whether or not a new key vault should be provisioned." 92 | } 93 | }, 94 | "keyVaultName": { 95 | "defaultValue": "[concat('kv', uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 96 | "type": "String", 97 | "metadata": { 98 | "description": "Name of the key vault." 99 | } 100 | }, 101 | "keyVaultBehindVNet": { 102 | "defaultValue": "false", 103 | "allowedValues": [ 104 | "true", 105 | "false" 106 | ], 107 | "type": "String", 108 | "metadata": { 109 | "description": "Determines whether or not to put the storage account behind VNet" 110 | } 111 | }, 112 | "keyVaultResourceGroupName": { 113 | "defaultValue": "[parameters('resourceGroupName')]", 114 | "type": "String" 115 | }, 116 | "keyVaultLocation": { 117 | "defaultValue": "[parameters('location')]", 118 | "type": "String" 119 | }, 120 | "applicationInsightsOption": { 121 | "defaultValue": "new", 122 | "allowedValues": [ 123 | "new", 124 | "existing" 125 | ], 126 | "type": "String", 127 | "metadata": { 128 | "description": "Determines whether or not new ApplicationInsights should be provisioned." 129 | } 130 | }, 131 | "logAnalyticsName": { 132 | "defaultValue": "[concat('la', uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 133 | "type": "String", 134 | "metadata": { 135 | "description": "Name of LogAnalytics to be used by ApplicationInsights resource." 136 | } 137 | }, 138 | "logAnalyticsArmId": { 139 | "defaultValue": "", 140 | "type": "String", 141 | "metadata": { 142 | "description": "ARM Id of LogAnalytics to be used by ApplicationInsights resource." 143 | } 144 | }, 145 | "applicationInsightsName": { 146 | "defaultValue": "[concat('ai', uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 147 | "type": "String", 148 | "metadata": { 149 | "description": "Name of ApplicationInsights." 150 | } 151 | }, 152 | "applicationInsightsResourceGroupName": { 153 | "defaultValue": "[parameters('resourceGroupName')]", 154 | "type": "String" 155 | }, 156 | "applicationInsightsLocation": { 157 | "defaultValue": "[parameters('location')]", 158 | "type": "String" 159 | }, 160 | "containerRegistryOption": { 161 | "defaultValue": "none", 162 | "allowedValues": [ 163 | "new", 164 | "existing", 165 | "none" 166 | ], 167 | "type": "String", 168 | "metadata": { 169 | "description": "Determines whether or not a new container registry should be provisioned." 170 | } 171 | }, 172 | "containerRegistryName": { 173 | "defaultValue": "[concat('cr', uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 174 | "type": "String", 175 | "metadata": { 176 | "description": "The container registry bind to the workspace." 177 | } 178 | }, 179 | "containerRegistrySku": { 180 | "defaultValue": "Standard", 181 | "allowedValues": [ 182 | "Basic", 183 | "Standard", 184 | "Premium" 185 | ], 186 | "type": "String" 187 | }, 188 | "containerRegistryResourceGroupName": { 189 | "defaultValue": "[parameters('resourceGroupName')]", 190 | "type": "String" 191 | }, 192 | "containerRegistryBehindVNet": { 193 | "defaultValue": "false", 194 | "allowedValues": [ 195 | "true", 196 | "false" 197 | ], 198 | "type": "String", 199 | "metadata": { 200 | "description": "Determines whether or not to put container registry behind VNet." 201 | } 202 | }, 203 | "containerRegistryLocation": { 204 | "defaultValue": "[parameters('location')]", 205 | "type": "String" 206 | }, 207 | "vnetOption": { 208 | "defaultValue": "[if(equals(parameters('privateEndpointType'), 'none'), 'none', 'new')]", 209 | "allowedValues": [ 210 | "new", 211 | "existing", 212 | "none" 213 | ], 214 | "type": "String", 215 | "metadata": { 216 | "description": "Determines whether or not a new VNet should be provisioned." 217 | } 218 | }, 219 | "vnetName": { 220 | "defaultValue": "[concat('vn',uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 221 | "type": "String", 222 | "metadata": { 223 | "description": "Name of the VNet" 224 | } 225 | }, 226 | "vnetResourceGroupName": { 227 | "defaultValue": "[parameters('resourceGroupName')]", 228 | "type": "String" 229 | }, 230 | "addressPrefixes": { 231 | "defaultValue": [ 232 | "10.0.0.0/16" 233 | ], 234 | "type": "Array", 235 | "metadata": { 236 | "description": "Address prefix of the virtual network" 237 | } 238 | }, 239 | "subnetOption": { 240 | "defaultValue": "[if(or(not(equals(parameters('privateEndpointType'), 'none')), equals(parameters('vnetOption'), 'new')), 'new', 'none')]", 241 | "allowedValues": [ 242 | "new", 243 | "existing", 244 | "none" 245 | ], 246 | "type": "String", 247 | "metadata": { 248 | "description": "Determines whether or not a new subnet should be provisioned." 249 | } 250 | }, 251 | "subnetName": { 252 | "defaultValue": "[concat('sn',uniqueString(parameters('resourceGroupName'), parameters('workspaceName')))]", 253 | "type": "String", 254 | "metadata": { 255 | "description": "Name of the subnet" 256 | } 257 | }, 258 | "subnetPrefix": { 259 | "defaultValue": "10.0.0.0/24", 260 | "type": "String", 261 | "metadata": { 262 | "description": "Subnet prefix of the virtual network" 263 | } 264 | }, 265 | "adbWorkspace": { 266 | "defaultValue": "", 267 | "type": "String", 268 | "metadata": { 269 | "description": "Azure Databrick workspace to be linked to the workspace" 270 | } 271 | }, 272 | "confidential_data": { 273 | "defaultValue": "false", 274 | "allowedValues": [ 275 | "false", 276 | "true" 277 | ], 278 | "type": "String", 279 | "metadata": { 280 | "description": "Specifies that the Azure Machine Learning workspace holds highly confidential data." 281 | } 282 | }, 283 | "encryption_status": { 284 | "defaultValue": "Disabled", 285 | "allowedValues": [ 286 | "Enabled", 287 | "Disabled" 288 | ], 289 | "type": "String", 290 | "metadata": { 291 | "description": "Specifies if the Azure Machine Learning workspace should be encrypted with customer managed key." 292 | } 293 | }, 294 | "cmk_keyvault": { 295 | "defaultValue": "", 296 | "type": "String", 297 | "metadata": { 298 | "description": "Specifies the customer managed keyVault arm id." 299 | } 300 | }, 301 | "resource_cmk_uri": { 302 | "defaultValue": "", 303 | "type": "String", 304 | "metadata": { 305 | "description": "Specifies if the customer managed keyvault key uri." 306 | } 307 | }, 308 | "privateEndpointType": { 309 | "defaultValue": "none", 310 | "allowedValues": [ 311 | "AutoApproval", 312 | "ManualApproval", 313 | "none" 314 | ], 315 | "type": "String" 316 | }, 317 | "tagValues": { 318 | "type": "Object" 319 | }, 320 | "privateEndpointName": { 321 | "defaultValue": "pe", 322 | "type": "String", 323 | "metadata": { 324 | "description": "Name of the private end point added to the workspace" 325 | } 326 | }, 327 | "privateEndpointResourceGroupName": { 328 | "defaultValue": "[parameters('resourceGroupName')]", 329 | "type": "String", 330 | "metadata": { 331 | "description": "Name of the resource group where the private end point is added to" 332 | } 333 | }, 334 | "imageBuildCompute": { 335 | "defaultValue": "", 336 | "type": "String", 337 | "metadata": { 338 | "description": "The name of the compute target to use for building environment Docker images with the container registry is behind a VNet." 339 | } 340 | }, 341 | "publicNetworkAccess": { 342 | "defaultValue": "Enabled", 343 | "allowedValues": [ 344 | "Disabled", 345 | "Enabled" 346 | ], 347 | "type": "String", 348 | "metadata": { 349 | "description": "Whether to allow public endpoint connectivity when a workspace is private link enabled." 350 | } 351 | }, 352 | "soft_delete_enabled": { 353 | "defaultValue": "false", 354 | "allowedValues": [ 355 | "false", 356 | "true" 357 | ], 358 | "type": "String", 359 | "metadata": { 360 | "description": "Whether to create a workspace with soft delete capability" 361 | } 362 | }, 363 | "allow_recover_softdeleted_workspace": { 364 | "defaultValue": "false", 365 | "allowedValues": [ 366 | "false", 367 | "true" 368 | ], 369 | "type": "String", 370 | "metadata": { 371 | "description": "Whether to allow an existing soft-deleted workspace to be recovered" 372 | } 373 | }, 374 | "encryption_cosmosdb_resourceid": { 375 | "defaultValue": "", 376 | "type": "String", 377 | "metadata": { 378 | "description": "The Bring-Your-Own cosmosdb account that customer brings to store data" 379 | } 380 | }, 381 | "encryption_storage_resourceid": { 382 | "defaultValue": "", 383 | "type": "String", 384 | "metadata": { 385 | "description": "The Bring-Your-Own storage account that customer brings to store data" 386 | } 387 | }, 388 | "encryption_search_resourceid": { 389 | "defaultValue": "", 390 | "type": "String", 391 | "metadata": { 392 | "description": "The Bring-Your-Own search account that customer brings to store data" 393 | } 394 | }, 395 | "identity": { 396 | "defaultValue": { 397 | "type": "systemAssigned" 398 | }, 399 | "type": "Object", 400 | "metadata": { 401 | "description": "Managed identities assigned to workspace. If not specificed, SystemAssigned managed identity is the default." 402 | } 403 | }, 404 | "primaryUserAssignedIdentity": { 405 | "defaultValue": "", 406 | "type": "String", 407 | "metadata": { 408 | "description": "ARM identifier of primary user assigned managed identity, in case multiple ones are specified. Also the default managed identity for clusterless compute." 409 | } 410 | }, 411 | "managedNetwork": { 412 | "defaultValue": { 413 | "isolationMode": "Disabled" 414 | }, 415 | "type": "Object", 416 | "metadata": { 417 | "description": "Managed network settings to be used for the workspace. If not specified, isolation mode Disabled is the default" 418 | } 419 | }, 420 | "spark_runtime_version": { 421 | "defaultValue": "", 422 | "type": "String", 423 | "metadata": { 424 | "description": "spark version to be used by all feature sets" 425 | } 426 | }, 427 | "offlineStoreStorageAccountOption": { 428 | "defaultValue": "none", 429 | "allowedValues": [ 430 | "new", 431 | "existing", 432 | "none" 433 | ], 434 | "type": "String", 435 | "metadata": { 436 | "description": "Determines whether or not to provision a feature store offline store storage account" 437 | } 438 | }, 439 | "offline_store_storage_account_name": { 440 | "defaultValue": "[concat('sa', uniqueString('featurestore', parameters('resourceGroupName'), parameters('workspaceName')))]", 441 | "type": "String", 442 | "metadata": { 443 | "description": "Name of the feature store offline store storage account." 444 | } 445 | }, 446 | "offline_store_container_name": { 447 | "defaultValue": "[concat('offlinestore', newGuid())]", 448 | "type": "String", 449 | "metadata": { 450 | "description": "Feature store offline store container" 451 | } 452 | }, 453 | "offline_store_resource_group_name": { 454 | "defaultValue": "[resourceGroup().name]", 455 | "type": "String", 456 | "metadata": { 457 | "description": "Feature store offline store resource group" 458 | } 459 | }, 460 | "offline_store_subscription_id": { 461 | "defaultValue": "[subscription().subscriptionId]", 462 | "type": "String", 463 | "metadata": { 464 | "description": "Feature store offline store subscription id" 465 | } 466 | }, 467 | "offline_store_connection_name": { 468 | "defaultValue": "", 469 | "type": "String", 470 | "metadata": { 471 | "description": "Feature store offline store config" 472 | } 473 | }, 474 | "online_store_resource_id": { 475 | "defaultValue": "", 476 | "type": "String", 477 | "metadata": { 478 | "description": "Feature store online store resource id" 479 | } 480 | }, 481 | "online_store_resource_group_name": { 482 | "defaultValue": "", 483 | "type": "String", 484 | "metadata": { 485 | "description": "Feature store online store resource group" 486 | } 487 | }, 488 | "online_store_subscription_id": { 489 | "defaultValue": "", 490 | "type": "String", 491 | "metadata": { 492 | "description": "Feature store online store subscription id" 493 | } 494 | }, 495 | "online_store_connection_name": { 496 | "defaultValue": "", 497 | "type": "String", 498 | "metadata": { 499 | "description": "Feature store online store config" 500 | } 501 | }, 502 | "materializationIdentityOption": { 503 | "defaultValue": "none", 504 | "allowedValues": [ 505 | "new", 506 | "existing", 507 | "none" 508 | ], 509 | "type": "String", 510 | "metadata": { 511 | "description": "Determines whether or not to provision a materialization identity" 512 | } 513 | }, 514 | "materialization_identity_name": { 515 | "defaultValue": "empty", 516 | "type": "String", 517 | "metadata": { 518 | "description": "Feature store materialization identity name" 519 | } 520 | }, 521 | "materialization_identity_subscription_id": { 522 | "defaultValue": "[subscription().subscriptionId]", 523 | "type": "String", 524 | "metadata": { 525 | "description": "Feature store materialization identity subscription id" 526 | } 527 | }, 528 | "materialization_identity_resource_group_name": { 529 | "defaultValue": "[resourceGroup().name]", 530 | "type": "String", 531 | "metadata": { 532 | "description": "Feature store materialization identity resource group name" 533 | } 534 | }, 535 | "grant_materialization_permissions": { 536 | "defaultValue": "false", 537 | "allowedValues": [ 538 | "false", 539 | "true" 540 | ], 541 | "type": "String", 542 | "metadata": { 543 | "description": "Whether to grant materialization identity permissions" 544 | } 545 | }, 546 | "enable_data_isolation": { 547 | "defaultValue": "false", 548 | "allowedValues": [ 549 | "false", 550 | "true" 551 | ], 552 | "type": "String", 553 | "metadata": { 554 | "description": "A flag to determine if workspace has data isolation enabled. The flag can only be set at the creation phase, it can't be updated." 555 | } 556 | }, 557 | "workspace_hub_config": { 558 | "defaultValue": {}, 559 | "type": "Object", 560 | "metadata": { 561 | "description": "Additional configuration for WorkspaceHub." 562 | } 563 | }, 564 | "existing_workspaces": { 565 | "defaultValue": [], 566 | "type": "Array", 567 | "metadata": { 568 | "description": "A list of existing workspaces used by Hub to perform convert." 569 | } 570 | }, 571 | "workspace_hub": { 572 | "defaultValue": "", 573 | "type": "String", 574 | "metadata": { 575 | "description": "Resource Id of Hub used for lean workspace." 576 | } 577 | }, 578 | "serverless_compute_settings": { 579 | "defaultValue": {}, 580 | "type": "Object", 581 | "metadata": { 582 | "description": "Serverless compute settings to be used for the workspace." 583 | } 584 | }, 585 | "endpoint_resource_id": { 586 | "defaultValue": "null", 587 | "type": "String", 588 | "metadata": { 589 | "description": "The resource id that this workspace hub's endpoints should reference." 590 | } 591 | }, 592 | "endpoint_kind": { 593 | "defaultValue": "AIServices", 594 | "type": "String", 595 | "metadata": { 596 | "description": "The kind of endpoints this workspace hub ought to contain." 597 | } 598 | }, 599 | "endpoint_option": { 600 | "defaultValue": "new", 601 | "type": "String", 602 | "metadata": { 603 | "description": "Testing value. Do not touch." 604 | } 605 | } 606 | }, 607 | "variables": { 608 | "tenantId": "[subscription().tenantId]", 609 | "storageAccount": "[resourceId(parameters('storageAccountResourceGroupName'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]", 610 | "keyVault": "[resourceId(parameters('keyVaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]", 611 | "containerRegistry": "[resourceId(parameters('containerRegistryResourceGroupName'), 'Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]", 612 | "applicationInsights": "[resourceId(parameters('applicationInsightsResourceGroupName'), 'Microsoft.Insights/components', parameters('applicationInsightsName'))]", 613 | "vnet": "[resourceId(parameters('vnetResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('vnetName'))]", 614 | "subnet": "[resourceId(parameters('vnetResourceGroupName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]", 615 | "enablePE": true, 616 | "networkRuleSetBehindVNet": { 617 | "defaultAction": "deny", 618 | "virtualNetworkRules": [{ 619 | "action": "Allow", 620 | "id": "[variables('subnet')]" 621 | }] 622 | }, 623 | "privateEndpointSettings": { 624 | "name": "[concat(parameters('workspaceName'), '-PrivateEndpoint')]", 625 | "properties": { 626 | "privateLinkServiceId": "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 627 | "groupIds": [ 628 | "amlworkspace" 629 | ] 630 | } 631 | }, 632 | "defaultPEConnections": "[array(variables('privateEndpointSettings'))]", 633 | "privateEndpointDeploymentName": "[concat('DeployPrivateEndpoint-', uniqueString(parameters('privateEndpointName')))]", 634 | "materializationIdentity": "[resourceId(parameters('materialization_identity_subscription_id'), parameters('materialization_identity_resource_group_name'), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]", 635 | "offlineStore": "[resourceId(parameters('offline_store_subscription_id'), parameters('offline_store_resource_group_name'), 'Microsoft.Storage/storageAccounts/blobServices/containers', parameters('offline_store_storage_account_name'), 'default', parameters('offline_store_container_name'))]", 636 | "isWorkspaceHub": "[equals(parameters('kind'), 'hub')]" 637 | }, 638 | "resources": [{ 639 | "type": "Microsoft.Network/virtualNetworks", 640 | "apiVersion": "2019-09-01", 641 | "name": "[parameters('vnetName')]", 642 | "location": "[parameters('location')]", 643 | "tags": "[parameters('tagValues')]", 644 | "properties": { 645 | "addressSpace": { 646 | "addressPrefixes": "[parameters('addressPrefixes')]" 647 | }, 648 | "enableDdosProtection": false, 649 | "enableVmProtection": false 650 | }, 651 | "condition": "[and(variables('enablePE'), equals(parameters('vnetOption'), 'new'))]" 652 | }, 653 | { 654 | "type": "Microsoft.Network/virtualNetworks/subnets", 655 | "apiVersion": "2019-09-01", 656 | "name": "[concat(parameters('vnetName'), '/', parameters('subnetName'))]", 657 | "dependsOn": [ 658 | "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]" 659 | ], 660 | "properties": { 661 | "addressPrefix": "[parameters('subnetPrefix')]", 662 | "privateEndpointNetworkPolicies": "Disabled", 663 | "privateLinkServiceNetworkPolicies": "Enabled", 664 | "serviceEndpoints": [{ 665 | "service": "Microsoft.Storage" 666 | }, 667 | { 668 | "service": "Microsoft.KeyVault" 669 | }, 670 | { 671 | "service": "Microsoft.ContainerRegistry" 672 | } 673 | ] 674 | }, 675 | "condition": "[and(variables('enablePE'), equals(parameters('subnetOption'), 'new'))]" 676 | }, 677 | { 678 | "type": "Microsoft.ManagedIdentity/userAssignedIdentities", 679 | "apiVersion": "2018-11-30", 680 | "name": "[parameters('materialization_identity_name')]", 681 | "location": "[parameters('location')]", 682 | "condition": "[and(equals(parameters('kind'), 'featurestore'), equals(parameters('materializationIdentityOption'), 'new'))]" 683 | }, 684 | { 685 | "type": "Microsoft.Storage/storageAccounts", 686 | "apiVersion": "2019-04-01", 687 | "name": "[parameters('storageAccountName')]", 688 | "location": "[parameters('storageAccountLocation')]", 689 | "dependsOn": [ 690 | "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" 691 | ], 692 | "tags": "[parameters('tagValues')]", 693 | "sku": { 694 | "name": "[parameters('storageAccountType')]" 695 | }, 696 | "kind": "StorageV2", 697 | "properties": { 698 | "encryption": { 699 | "services": { 700 | "blob": { 701 | "enabled": true 702 | }, 703 | "file": { 704 | "enabled": true 705 | } 706 | }, 707 | "keySource": "Microsoft.Storage" 708 | }, 709 | "supportsHttpsTrafficOnly": true, 710 | "allowBlobPublicAccess": false, 711 | "networkAcls": "[if(equals(parameters('storageAccountBehindVNet'), 'true'), variables('networkRuleSetBehindVNet'), json('null'))]", 712 | "isHnsEnabled": "[equals(parameters('kind'), 'featurestore')]", 713 | "minimumTlsVersion": "[if(equals(parameters('kind'), 'featurestore'), 'TLS1_2', 'TLS1_0')]" 714 | }, 715 | "condition": "[and(variables('enablePE'), equals(parameters('storageAccountOption'), 'new'))]" 716 | }, 717 | { 718 | "type": "Microsoft.Storage/storageAccounts", 719 | "apiVersion": "2019-04-01", 720 | "name": "[parameters('offline_store_storage_account_name')]", 721 | "location": "[parameters('location')]", 722 | "tags": "[parameters('tagValues')]", 723 | "sku": { 724 | "name": "Standard_LRS" 725 | }, 726 | "kind": "StorageV2", 727 | "properties": { 728 | "encryption": { 729 | "services": { 730 | "blob": { 731 | "enabled": true 732 | }, 733 | "file": { 734 | "enabled": true 735 | } 736 | }, 737 | "keySource": "Microsoft.Storage" 738 | }, 739 | "supportsHttpsTrafficOnly": true, 740 | "allowBlobPublicAccess": false, 741 | "networkAcls": "[json('null')]", 742 | "isHnsEnabled": true, 743 | "minimumTlsVersion": "TLS1_2" 744 | }, 745 | "condition": "[and(variables('enablePE'), equals(parameters('kind'), 'featurestore'), equals(parameters('storageAccountOption'), 'existing'), equals(parameters('offlineStoreStorageAccountOption'), 'new'))]" 746 | }, 747 | { 748 | "type": "Microsoft.Storage/storageAccounts/blobServices/containers", 749 | "apiVersion": "2021-04-01", 750 | "name": "[concat(parameters('offline_store_storage_account_name'), '/default/', parameters('offline_store_container_name'))]", 751 | "dependsOn": [ 752 | "[resourceId('Microsoft.Storage/storageAccounts', parameters('offline_store_storage_account_name'))]" 753 | ], 754 | "condition": "[and(variables('enablePE'), equals(parameters('kind'), 'featurestore'), equals(parameters('offlineStoreStorageAccountOption'), 'new'))]" 755 | }, 756 | { 757 | "type": "Microsoft.KeyVault/vaults", 758 | "apiVersion": "2019-09-01", 759 | "name": "[parameters('keyVaultName')]", 760 | "location": "[parameters('keyVaultLocation')]", 761 | "dependsOn": [ 762 | "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" 763 | ], 764 | "tags": "[parameters('tagValues')]", 765 | "properties": { 766 | "tenantId": "[variables('tenantId')]", 767 | "sku": { 768 | "name": "standard", 769 | "family": "A" 770 | }, 771 | "accessPolicies": [], 772 | "enableRbacAuthorization": true, 773 | "networkAcls": "[if(equals(parameters('keyVaultBehindVNet'), 'true'), variables('networkRuleSetBehindVNet'), json('null'))]" 774 | }, 775 | "condition": "[and(variables('enablePE'), equals(parameters('keyVaultOption'), 'new'))]" 776 | }, 777 | { 778 | "type": "Microsoft.ContainerRegistry/registries", 779 | "apiVersion": "2019-05-01", 780 | "name": "[parameters('containerRegistryName')]", 781 | "location": "[parameters('containerRegistryLocation')]", 782 | "dependsOn": [ 783 | "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" 784 | ], 785 | "tags": "[parameters('tagValues')]", 786 | "sku": { 787 | "name": "[parameters('containerRegistrySku')]" 788 | }, 789 | "properties": { 790 | "adminUserEnabled": true, 791 | "networkRuleSet": "[if(equals(parameters('containerRegistryBehindVNet'), 'true'), variables('networkRuleSetBehindVNet'), json('null'))]" 792 | }, 793 | "condition": "[and(variables('enablePE'), equals(parameters('containerRegistryOption'), 'new'))]" 794 | }, 795 | { 796 | "type": "Microsoft.OperationalInsights/workspaces", 797 | "apiVersion": "2020-08-01", 798 | "name": "[parameters('logAnalyticsName')]", 799 | "location": "[if(or(equals(toLower(parameters('applicationInsightsLocation')),'westcentralus'), equals(toLower(parameters('applicationInsightsLocation')),'eastus2euap'), equals(toLower(parameters('applicationInsightsLocation')),'centraluseuap')),'southcentralus', parameters('applicationInsightsLocation'))]", 800 | "tags": "[parameters('tagValues')]", 801 | "kind": "web", 802 | "properties": { 803 | "Application_Type": "web" 804 | }, 805 | "condition": "[and(variables('enablePE'), equals(parameters('applicationInsightsOption'), 'new'))]" 806 | }, 807 | { 808 | "type": "Microsoft.Insights/components", 809 | "apiVersion": "2020-02-02-preview", 810 | "name": "[parameters('applicationInsightsName')]", 811 | "location": "[if(or(equals(toLower(parameters('applicationInsightsLocation')),'westcentralus'), equals(toLower(parameters('applicationInsightsLocation')),'eastus2euap'), equals(toLower(parameters('applicationInsightsLocation')),'centraluseuap')),'southcentralus', parameters('applicationInsightsLocation'))]", 812 | "dependsOn": [ 813 | "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsName'))]" 814 | ], 815 | "tags": "[parameters('tagValues')]", 816 | "kind": "web", 817 | "properties": { 818 | "Application_Type": "web", 819 | "WorkspaceResourceId": "[parameters('logAnalyticsArmId')]" 820 | }, 821 | "condition": "[and(variables('enablePE'), equals(parameters('applicationInsightsOption'), 'new'))]" 822 | }, 823 | { 824 | "type": "Microsoft.MachineLearningServices/workspaces", 825 | "apiVersion": "2023-08-01-preview", 826 | "name": "[parameters('workspaceName')]", 827 | "location": "[parameters('location')]", 828 | "dependsOn": [ 829 | "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]", 830 | "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]", 831 | "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]", 832 | "[resourceId('Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]" 833 | ], 834 | "tags": "[parameters('tagValues')]", 835 | "kind": "[parameters('kind')]", 836 | "identity": "[parameters('identity')]", 837 | "properties": { 838 | "friendlyName": "[parameters('friendlyName')]", 839 | "description": "[parameters('description')]", 840 | "storageAccount": "[variables('storageAccount')]", 841 | "keyVault": "[variables('keyVault')]", 842 | "applicationInsights": "[variables('applicationInsights')]", 843 | "containerRegistry": "[if(not(equals(parameters('containerRegistryOption'), 'none')), variables('containerRegistry'), json('null'))]", 844 | "hbiWorkspace": "[parameters('confidential_data')]", 845 | "imageBuildCompute": "[parameters('imageBuildCompute')]", 846 | "publicNetworkAccess": "[parameters('publicNetworkAccess')]", 847 | "softDeleteEnabled": "[parameters('soft_delete_enabled')]", 848 | "allowRecoverSoftDeletedWorkspace": "[parameters('allow_recover_softdeleted_workspace')]", 849 | "encryption": { 850 | "status": "[parameters('encryption_status')]", 851 | "keyVaultProperties": { 852 | "keyVaultArmId": "[parameters('cmk_keyvault')]", 853 | "keyIdentifier": "[parameters('resource_cmk_uri')]" 854 | }, 855 | "cosmosDbArmId": "[parameters('encryption_cosmosdb_resourceid')]", 856 | "storageAccountArmId": "[parameters('encryption_storage_resourceid')]", 857 | "SearchAccountArmId": "[parameters('encryption_search_resourceid')]" 858 | }, 859 | "primaryUserAssignedIdentity": "[parameters('primaryUserAssignedIdentity')]", 860 | "managedNetwork": "[parameters('managedNetwork')]", 861 | "featureStoreSettings": { 862 | "computeruntime": { 863 | "SparkRuntimeVersion": "[parameters('spark_runtime_version')]" 864 | } 865 | }, 866 | "enableDataIsolation": "[parameters('enable_data_isolation')]", 867 | "workspaceHubConfig": "[parameters('workspace_hub_config')]", 868 | "existingWorkspaces": "[parameters('existing_workspaces')]", 869 | "serverlessComputeSettings": "[parameters('serverless_compute_settings')]" 870 | }, 871 | "resources": [{ 872 | "type": "connections", 873 | "apiVersion": "2022-05-01", 874 | "name": "[if(empty(parameters('offline_store_connection_name')), 'empty', parameters('offline_store_connection_name'))]", 875 | "location": "[parameters('location')]", 876 | "dependsOn": [ 877 | "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 878 | "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('offline_store_storage_account_name'), 'default', parameters('offline_store_container_name'))]", 879 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]" 880 | ], 881 | "identity": { 882 | "type": "SystemAssigned" 883 | }, 884 | "properties": { 885 | "category": "AzureDataLakeGen2", 886 | "target": "[variables('offlineStore')]", 887 | "authType": "ManagedIdentity", 888 | "credentials": { 889 | "clientid": "[if(not(equals(parameters('materializationIdentityOption'), 'none')), reference(variables('materializationIdentity'), '2018-11-30').clientId, '')]", 890 | "resourceid": "[variables('materializationIdentity')]" 891 | } 892 | }, 893 | "condition": "[equals(parameters('kind'), 'featurestore')]" 894 | }, 895 | { 896 | "type": "connections", 897 | "apiVersion": "2022-05-01", 898 | "name": "[if(empty(parameters('online_store_connection_name')), 'empty', parameters('online_store_connection_name'))]", 899 | "location": "[parameters('location')]", 900 | "dependsOn": [ 901 | "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 902 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]" 903 | ], 904 | "identity": { 905 | "type": "SystemAssigned" 906 | }, 907 | "properties": { 908 | "category": "Redis", 909 | "target": "[parameters('online_store_resource_id')]", 910 | "authType": "ManagedIdentity", 911 | "credentials": { 912 | "clientid": "[if(not(equals(parameters('materializationIdentityOption'), 'none')), reference(variables('materializationIdentity'), '2018-11-30').clientId, '')]", 913 | "resourceid": "[variables('materializationIdentity')]" 914 | } 915 | }, 916 | "condition": "[and(equals(parameters('kind'), 'featurestore'), not(empty(parameters('online_store_resource_id'))))]" 917 | }, 918 | { 919 | "type": "endpoints", 920 | "apiVersion": "2023-08-01-preview", 921 | "name": "Azure.OpenAI", 922 | "dependsOn": [ 923 | "[parameters('workspaceName')]" 924 | ], 925 | "properties": { 926 | "name": "Azure.OpenAI", 927 | "endpointType": "Azure.OpenAI", 928 | "associatedResourceId": "[if(equals(parameters('endpoint_resource_id'), 'null'), null(), parameters('endpoint_resource_id'))]" 929 | }, 930 | "condition": "[and(equals(parameters('endpoint_option'), 'new'), variables('isWorkspaceHub'))]" 931 | }, 932 | { 933 | "type": "endpoints", 934 | "apiVersion": "2023-08-01-preview", 935 | "name": "Azure.ContentSafety", 936 | "dependsOn": [ 937 | "[parameters('workspaceName')]" 938 | ], 939 | "properties": { 940 | "name": "Azure.ContentSafety", 941 | "endpointType": "Azure.ContentSafety", 942 | "associatedResourceId": "[if(equals(parameters('endpoint_resource_id'), 'null'), null(), parameters('endpoint_resource_id'))]" 943 | }, 944 | "condition": "[and(equals(parameters('endpoint_kind'), 'AIServices'), equals(parameters('endpoint_option'), 'new'), variables('isWorkspaceHub'))]" 945 | }, 946 | { 947 | "type": "endpoints", 948 | "apiVersion": "2023-08-01-preview", 949 | "name": "Azure.Speech", 950 | "dependsOn": [ 951 | "[parameters('workspaceName')]" 952 | ], 953 | "properties": { 954 | "name": "Azure.Speech", 955 | "endpointType": "Azure.Speech", 956 | "associatedResourceId": "[if(equals(parameters('endpoint_resource_id'), 'null'), null(), parameters('endpoint_resource_id'))]" 957 | }, 958 | "condition": "[and(equals(parameters('endpoint_kind'), 'AIServices'), equals(parameters('endpoint_option'), 'new'), variables('isWorkspaceHub'))]" 959 | } 960 | ], 961 | "condition": "[variables('enablePE')]" 962 | }, 963 | { 964 | "type": "Microsoft.Resources/deployments", 965 | "apiVersion": "2022-05-01", 966 | "name": "[concat(parameters('workspaceName'), '-deploy-feature-store')]", 967 | "dependsOn": [ 968 | "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 969 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]", 970 | "[resourceId('Microsoft.MachineLearningServices/workspaces/connections', parameters('workspaceName'), parameters('offline_store_connection_name'))]", 971 | "[resourceId('Microsoft.MachineLearningServices/workspaces/connections', parameters('workspaceName'), parameters('online_store_connection_name'))]" 972 | ], 973 | "properties": { 974 | "mode": "Incremental", 975 | "parameters": {}, 976 | "template": { 977 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 978 | "contentVersion": "1.0.0.1", 979 | "resources": [{ 980 | "apiVersion": "2022-12-01-preview", 981 | "name": "[parameters('workspaceName')]", 982 | "location": "[parameters('location')]", 983 | "kind": "featurestore", 984 | "type": "Microsoft.MachineLearningServices/workspaces", 985 | "identity": { 986 | "type": "SystemAssigned,UserAssigned", 987 | "userAssignedIdentities": { 988 | "[variables('materializationIdentity')]": {} 989 | } 990 | }, 991 | "properties": { 992 | "friendlyName": "[parameters('friendlyName')]", 993 | "description": "[parameters('description')]", 994 | "storageAccount": "[variables('storageAccount')]", 995 | "keyVault": "[variables('keyVault')]", 996 | "applicationInsights": "[variables('applicationInsights')]", 997 | "containerRegistry": "[if(not(equals(parameters('containerRegistryOption'), 'none')), variables('containerRegistry'), json('null'))]", 998 | "hbiWorkspace": "[parameters('confidential_data')]", 999 | "imageBuildCompute": "[parameters('imageBuildCompute')]", 1000 | "publicNetworkAccess": "[parameters('publicNetworkAccess')]", 1001 | "softDeleteEnabled": "[parameters('soft_delete_enabled')]", 1002 | "allowRecoverSoftDeletedWorkspace": "[parameters('allow_recover_softdeleted_workspace')]", 1003 | "encryption": { 1004 | "status": "[parameters('encryption_status')]", 1005 | "keyVaultProperties": { 1006 | "keyVaultArmId": "[parameters('cmk_keyvault')]", 1007 | "keyIdentifier": "[parameters('resource_cmk_uri')]" 1008 | }, 1009 | "cosmosDbArmId": "[parameters('encryption_cosmosdb_resourceid')]", 1010 | "storageAccountArmId": "[parameters('encryption_storage_resourceid')]", 1011 | "SearchAccountArmId": "[parameters('encryption_search_resourceid')]" 1012 | }, 1013 | "primaryUserAssignedIdentity": "[parameters('primaryUserAssignedIdentity')]", 1014 | "managedNetwork": "[parameters('managedNetwork')]", 1015 | "featureStoreSettings": { 1016 | "computeruntime": { 1017 | "SparkRuntimeVersion": "[parameters('spark_runtime_version')]" 1018 | }, 1019 | "offlinestoreconnectionname": "[parameters('offline_store_connection_name')]", 1020 | "onlinestoreconnectionname": "[parameters('online_store_connection_name')]" 1021 | }, 1022 | "enableDataIsolation": "[parameters('enable_data_isolation')]" 1023 | } 1024 | }] 1025 | } 1026 | }, 1027 | "condition": "[equals(parameters('kind'), 'featurestore')]" 1028 | }, 1029 | { 1030 | "type": "Microsoft.Resources/deployments", 1031 | "apiVersion": "2020-06-01", 1032 | "name": "[concat('workspace-role-assign-', guid(variables('materializationIdentity'), resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName')), 'azureml ds role'))]", 1033 | "dependsOn": [ 1034 | "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 1035 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]" 1036 | ], 1037 | "properties": { 1038 | "mode": "Incremental", 1039 | "template": { 1040 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 1041 | "contentVersion": "1.0.0.0", 1042 | "resources": [{ 1043 | "type": "Microsoft.Authorization/roleAssignments", 1044 | "apiVersion": "2022-04-01", 1045 | "name": "[guid(variables('materializationIdentity'), resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName')), 'azureml ds role')]", 1046 | "scope": "[resourceId(resourceGroup().name, 'Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 1047 | "properties": { 1048 | "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f6c7c914-8db3-469d-8ca1-694a8f32e121')]", 1049 | "principalId": "[if(not(equals(parameters('materializationIdentityOption'), 'none')), reference(variables('materializationIdentity'), '2018-11-30').principalId, '')]", 1050 | "principalType": "ServicePrincipal" 1051 | } 1052 | }] 1053 | } 1054 | }, 1055 | "condition": "[and(equals(parameters('kind'), 'featurestore'), equals(parameters('grant_materialization_permissions'), 'true'))]" 1056 | }, 1057 | { 1058 | "type": "Microsoft.Resources/deployments", 1059 | "apiVersion": "2020-06-01", 1060 | "name": "[concat('offline-store-role-assign-', guid(variables('materializationIdentity'), variables('offlineStore'), 'storage blob data contributor'))]", 1061 | "dependsOn": [ 1062 | "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', parameters('offline_store_storage_account_name'), 'default', parameters('offline_store_container_name'))]", 1063 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]" 1064 | ], 1065 | "properties": { 1066 | "mode": "Incremental", 1067 | "template": { 1068 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 1069 | "contentVersion": "1.0.0.0", 1070 | "resources": [{ 1071 | "type": "Microsoft.Authorization/roleAssignments", 1072 | "apiVersion": "2022-04-01", 1073 | "name": "[guid(variables('materializationIdentity'), variables('offlineStore'), 'storage blob data contributor')]", 1074 | "scope": "[variables('offlineStore')]", 1075 | "properties": { 1076 | "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", 1077 | "principalId": "[if(not(equals(parameters('materializationIdentityOption'), 'none')), reference(variables('materializationIdentity'), '2023-01-31').principalId, '')]", 1078 | "principalType": "ServicePrincipal" 1079 | } 1080 | }] 1081 | } 1082 | }, 1083 | "subscriptionId": "[parameters('offline_store_subscription_id')]", 1084 | "resourceGroup": "[parameters('offline_store_resource_group_name')]", 1085 | "condition": "[and(equals(parameters('kind'), 'featurestore'), equals(parameters('grant_materialization_permissions'), 'true'), not(equals(parameters('materializationIdentityOption'), 'none')))]" 1086 | }, 1087 | { 1088 | "type": "Microsoft.Resources/deployments", 1089 | "apiVersion": "2020-06-01", 1090 | "name": "[concat('online-store-role-assign-', guid(variables('materializationIdentity'), parameters('online_store_resource_id'), 'contributor'))]", 1091 | "dependsOn": [ 1092 | "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('materialization_identity_name'))]" 1093 | ], 1094 | "properties": { 1095 | "mode": "Incremental", 1096 | "template": { 1097 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 1098 | "contentVersion": "1.0.0.0", 1099 | "resources": [{ 1100 | "type": "Microsoft.Authorization/roleAssignments", 1101 | "apiVersion": "2022-04-01", 1102 | "name": "[guid(variables('materializationIdentity'), parameters('online_store_resource_id'), 'contributor')]", 1103 | "scope": "[parameters('online_store_resource_id')]", 1104 | "properties": { 1105 | "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", 1106 | "principalId": "[if(not(equals(parameters('materializationIdentityOption'), 'none')), reference(variables('materializationIdentity'), '2023-01-31').principalId, '')]", 1107 | "principalType": "ServicePrincipal" 1108 | } 1109 | }] 1110 | } 1111 | }, 1112 | "subscriptionId": "[parameters('online_store_subscription_id')]", 1113 | "resourceGroup": "[parameters('online_store_resource_group_name')]", 1114 | "condition": "[and(equals(parameters('kind'), 'featurestore'), equals(parameters('grant_materialization_permissions'), 'true'), not(equals(parameters('materializationIdentityOption'), 'none')), not(empty(parameters('online_store_resource_id'))))]" 1115 | }, 1116 | { 1117 | "type": "Microsoft.Resources/deployments", 1118 | "apiVersion": "2020-06-01", 1119 | "name": "[variables('privateEndpointDeploymentName')]", 1120 | "dependsOn": [ 1121 | "[resourceId('Microsoft.MachineLearningServices/workspaces', parameters('workspaceName'))]", 1122 | "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" 1123 | ], 1124 | "properties": { 1125 | "mode": "Incremental", 1126 | "template": { 1127 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", 1128 | "contentVersion": "1.0.0.0", 1129 | "resources": [{ 1130 | "apiVersion": "2020-06-01", 1131 | "name": "[parameters('privateEndpointName')]", 1132 | "type": "Microsoft.Network/privateEndpoints", 1133 | "location": "[parameters('location')]", 1134 | "tags": "[parameters('tagValues')]", 1135 | "properties": { 1136 | "privateLinkServiceConnections": "[if(equals(parameters('privateEndpointType'), 'AutoApproval'), variables('defaultPEConnections'), json('null'))]", 1137 | "manualPrivateLinkServiceConnections": "[if(equals(parameters('privateEndpointType'), 'ManualApproval'), variables('defaultPEConnections'), json('null'))]", 1138 | "subnet": { 1139 | "id": "[variables('subnet')]" 1140 | } 1141 | } 1142 | }] 1143 | } 1144 | }, 1145 | "resourceGroup": "[parameters('privateEndpointResourceGroupName')]", 1146 | "condition": "[and(variables('enablePE'), not(equals(parameters('privateEndpointType'), 'none')))]" 1147 | } 1148 | ] 1149 | } -------------------------------------------------------------------------------- /cli/cli-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OscarSantosMu/azure-ml-workspace-creation/ef4f5ec318e639ccc1c4080c4f7be0c16e8ae90a/cli/cli-demo.png -------------------------------------------------------------------------------- /cli/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | To create an Azure Machine Learning from the CLI, you can follow these instructions: 4 | 5 | Open the Azure Cloud Shell in the Azure portal or install the Azure CLI in your terminal if you haven't already. 6 | 7 | If you have the script.sh file, you can run it directly in the Azure Cloud Shell or copy and paste the commands line by line into your terminal. Before running the script or individual commands locally using az cli, make sure you are logged in to your Azure account using the `az login` command. 8 | 9 | If you are using the Azure Cloud Shell, you can skip the installation of the Azure CLI as it is already pre-installed. 10 | 11 | If you are using your own terminal, you can install the Azure CLI by following the instructions provided by Microsoft for your specific operating system. 12 | 13 | Follow any prompts or provide necessary inputs as required during the execution of the script or individual commands. 14 | 15 | After the execution is complete, you should have successfully created an Azure Machine Learning workspace. 16 | 17 | ![](cli-demo.png) 18 | 19 | Remember to review the script or individual commands before running them to ensure they align with your requirements and environment. -------------------------------------------------------------------------------- /cli/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # az login 4 | export RESOURCE_GROUP="" 5 | export WORKSPACE_NAME="mlw-dp100-cli" 6 | 7 | az extension remove -n azure-cli-ml 8 | az extension remove -n ml 9 | az extension add -n ml -y 10 | az group create --name "$RESOURCE_GROUP" --location "eastus" 11 | az ml workspace create --name "$WORKSPACE_NAME" -g "$RESOURCE_GROUP" -------------------------------------------------------------------------------- /portal/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | To create an Azure Machine Learning workspace from the Azure portal, you can follow these steps: 4 | 5 | 1. Sign in to the Azure portal (https://portal.azure.com). 6 | 2. Click on the "+ Create a resource" button on the top left corner of the portal. 7 | 3. In the search bar, type "Azure Machine Learning" and select "Azure Machine Learning" from the results. 8 | 4. Click on the "Create" button to start creating a new Azure Machine Learning workspace. 9 | 5. In the "Basics" tab, provide a unique name for your workspace. 10 | 6. Select the subscription, resource group, and region for your workspace. 11 | 7. Click on the "Next: Networking" button to proceed to the next step. 12 | 8. Configure the networking settings according to your requirements (for demo purposes you can leave it with the default values). 13 | 9. Click on the "Next: Encryption" button to proceed to the next step. 14 | 10. Configure the data encryption settings according to your requirements. (for demo purposes you can leave it with the default values). 15 | 11. Click on the "Next: Identity" button to proceed to the next step. 16 | 12. Configure the identity settings according to your requirements. (for demo purposes you can leave it with the default values). 17 | 13. Click on the "Next: Tags" button to proceed to the next step. 18 | 14. Configure the tags settings as needed. (for demo purposes you can leave it with the default values). 19 | 15. Click on the "Review + create" button to review your workspace configuration. 20 | 16. After reviewing, click on the "Create" button to create the Azure Machine Learning workspace. 21 | 17. Wait for the deployment to complete. This may take a few minutes. 22 | 18. Once the deployment is successful, you can access your Azure Machine Learning workspace from the Azure portal. 23 | 24 | Your resource group should look something like this 25 | 26 | ![](portal-demo.png) -------------------------------------------------------------------------------- /portal/portal-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OscarSantosMu/azure-ml-workspace-creation/ef4f5ec318e639ccc1c4080c4f7be0c16e8ae90a/portal/portal-demo.png -------------------------------------------------------------------------------- /sdk/.env.example: -------------------------------------------------------------------------------- 1 | SUBSCRIPTION_ID=12345 2 | RESOURCE_GROUP=resourcegroup 3 | -------------------------------------------------------------------------------- /sdk/connect_to_workspace.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from azure.ai.ml import MLClient 4 | from azure.identity import DefaultAzureCredential 5 | from dotenv import load_dotenv 6 | 7 | load_dotenv() # take environment variables from .env. 8 | 9 | subscription_id = os.getenv("SUBSCRIPTION_ID") # preferably using env variable 10 | resource_group = os.getenv("RESOURCE_GROUP") # preferably using env variable 11 | workspace = os.getenv("WORKSPACE") # preferably using env variable 12 | 13 | if workspace is None: 14 | ml_client = MLClient(DefaultAzureCredential(), subscription_id, resource_group) 15 | else: 16 | ml_client = MLClient( 17 | DefaultAzureCredential(), subscription_id, resource_group, workspace 18 | ) 19 | -------------------------------------------------------------------------------- /sdk/create_workspace.py: -------------------------------------------------------------------------------- 1 | from azure.ai.ml.entities import Workspace 2 | from connect_to_workspace import ml_client 3 | 4 | workspace_name = "mlw-dp100-sdk" 5 | 6 | ws_basic = Workspace( 7 | name=workspace_name, 8 | location="eastus", 9 | display_name="Basic workspace-example", 10 | description="This example shows how to create a basic workspace", 11 | ) 12 | ml_client.workspaces.begin_create(ws_basic) 13 | -------------------------------------------------------------------------------- /sdk/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Create a virtualenv 4 | 5 | ```console 6 | python -m venv venv 7 | ``` 8 | 9 | For Windows 10 | ``` 11 | venv\Scripts\activate 12 | ``` 13 | 14 | For Linux or macOS 15 | ``` 16 | source venv/bin/activate 17 | ``` 18 | 19 | Install the Azure Machine Learning SDK by running the following command in your terminal or command prompt: 20 | 21 | ```console 22 | pip install -r requirements.txt 23 | ``` 24 | 25 | Create a .env file like the .env.example and replace the values of these variables with your subscription and resource group. 26 | 27 | Run the Python script named create_workspace.py 28 | 29 | ```python 30 | python create_workspace.py 31 | ``` -------------------------------------------------------------------------------- /sdk/requirements.txt: -------------------------------------------------------------------------------- 1 | azure-ai-ml 2 | python-dotenv --------------------------------------------------------------------------------