From db3e33b8c8596a01710ad49122416ab489da47fd Mon Sep 17 00:00:00 2001 From: Chinedum Echeta <60179183+cecheta@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:22:41 +0100 Subject: [PATCH] feat: `avm/res/machine-learning-services/workspace` Add connections (#3027) ## Description Closes #2575. Adds connections to the module. ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.machine-learning-services.workspace](https://github.com/cecheta/bicep-registry-modules/actions/workflows/avm.res.machine-learning-services.workspace.yml/badge.svg?branch=ml-workspace-connections)](https://github.com/cecheta/bicep-registry-modules/actions/workflows/avm.res.machine-learning-services.workspace.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [ ] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../workspace/README.md | 282 +++ .../workspace/connection/README.md | 247 ++ .../workspace/connection/main.bicep | 393 +++ .../workspace/connection/main.json | 723 ++++++ .../workspace/main.bicep | 55 + .../workspace/main.json | 2136 ++++++++++++++--- .../workspace/tests/e2e/ai/dependencies.bicep | 21 + .../workspace/tests/e2e/ai/main.test.bicep | 21 + .../workspace/tests/e2e/max/main.test.bicep | 13 + .../workspace/version.json | 12 +- 10 files changed, 3587 insertions(+), 316 deletions(-) create mode 100644 avm/res/machine-learning-services/workspace/connection/README.md create mode 100644 avm/res/machine-learning-services/workspace/connection/main.bicep create mode 100644 avm/res/machine-learning-services/workspace/connection/main.json diff --git a/avm/res/machine-learning-services/workspace/README.md b/avm/res/machine-learning-services/workspace/README.md index c67fdf5391..b7f3752a25 100644 --- a/avm/res/machine-learning-services/workspace/README.md +++ b/avm/res/machine-learning-services/workspace/README.md @@ -21,6 +21,7 @@ This module deploys a Machine Learning Services Workspace. | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.MachineLearningServices/workspaces` | [2024-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01-preview/workspaces) | | `Microsoft.MachineLearningServices/workspaces/computes` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2022-10-01/workspaces/computes) | +| `Microsoft.MachineLearningServices/workspaces/connections` | [2024-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01/workspaces/connections) | | `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | @@ -59,6 +60,26 @@ module workspace 'br/public:avm/res/machine-learning-services/workspace:' associatedKeyVaultResourceId: '' associatedStorageAccountResourceId: '' + connections: [ + { + category: 'AIServices' + connectionProperties: { + authType: 'ApiKey' + credentials: { + key: 'key' + } + } + metadata: { + ApiType: 'Azure' + ApiVersion: '2023-07-01-preview' + DeploymentApiVersion: '2023-10-01-preview' + Location: '' + ResourceId: '' + } + name: 'ai' + target: '' + } + ] kind: 'Hub' location: '' workspaceHubConfig: { @@ -98,6 +119,28 @@ module workspace 'br/public:avm/res/machine-learning-services/workspace:" }, + "connections": { + "value": [ + { + "category": "AIServices", + "connectionProperties": { + "authType": "ApiKey", + "credentials": { + "key": "key" + } + }, + "metadata": { + "ApiType": "Azure", + "ApiVersion": "2023-07-01-preview", + "DeploymentApiVersion": "2023-10-01-preview", + "Location": "", + "ResourceId": "" + }, + "name": "ai", + "target": "" + } + ] + }, "kind": { "value": "Hub" }, @@ -433,6 +476,19 @@ module workspace 'br/public:avm/res/machine-learning-services/workspace:Any_other_property<`](#parameter-connectionsmetadata>any_other_property<) | string | The metadata key-value pairs. | + +### Parameter: `connections.metadata.>Any_other_property<` + +The metadata key-value pairs. + +- Required: Yes +- Type: string + +### Parameter: `connections.sharedUserList` + +The shared user list of the connection. + +- Required: No +- Type: array + +### Parameter: `connections.value` + +Value details of the workspace connection. + +- Required: No +- Type: string + ### Parameter: `customerManagedKey` The customer managed key definition. diff --git a/avm/res/machine-learning-services/workspace/connection/README.md b/avm/res/machine-learning-services/workspace/connection/README.md new file mode 100644 index 0000000000..7321660f73 --- /dev/null +++ b/avm/res/machine-learning-services/workspace/connection/README.md @@ -0,0 +1,247 @@ +# Machine Learning Services Workspaces Connections `[Microsoft.MachineLearningServices/workspaces/connections]` + +This module creates a connection in a Machine Learning Services workspace. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.MachineLearningServices/workspaces/connections` | [2024-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2024-04-01/workspaces/connections) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-category) | string | Category of the connection. | +| [`connectionProperties`](#parameter-connectionproperties) | secureObject | The properties of the connection, specific to the auth type. | +| [`machineLearningWorkspaceName`](#parameter-machinelearningworkspacename) | string | The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment. | +| [`name`](#parameter-name) | string | Name of the connection to create. | +| [`target`](#parameter-target) | string | The target of the connection. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`expiryTime`](#parameter-expirytime) | string | The expiry time of the connection. | +| [`isSharedToAll`](#parameter-issharedtoall) | bool | Indicates whether the connection is shared to all users in the workspace. | +| [`metadata`](#parameter-metadata) | object | User metadata for the connection. | +| [`sharedUserList`](#parameter-shareduserlist) | array | The shared user list of the connection. | +| [`value`](#parameter-value) | string | Value details of the workspace connection. | + +### Parameter: `category` + +Category of the connection. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'ADLSGen2' + 'AIServices' + 'AmazonMws' + 'AmazonRdsForOracle' + 'AmazonRdsForSqlServer' + 'AmazonRedshift' + 'AmazonS3Compatible' + 'ApiKey' + 'AzureBlob' + 'AzureDatabricksDeltaLake' + 'AzureDataExplorer' + 'AzureMariaDb' + 'AzureMySqlDb' + 'AzureOneLake' + 'AzureOpenAI' + 'AzurePostgresDb' + 'AzureSqlDb' + 'AzureSqlMi' + 'AzureSynapseAnalytics' + 'AzureTableStorage' + 'BingLLMSearch' + 'Cassandra' + 'CognitiveSearch' + 'CognitiveService' + 'Concur' + 'ContainerRegistry' + 'CosmosDb' + 'CosmosDbMongoDbApi' + 'Couchbase' + 'CustomKeys' + 'Db2' + 'Drill' + 'Dynamics' + 'DynamicsAx' + 'DynamicsCrm' + 'Eloqua' + 'FileServer' + 'FtpServer' + 'GenericContainerRegistry' + 'GenericHttp' + 'GenericRest' + 'Git' + 'GoogleAdWords' + 'GoogleBigQuery' + 'GoogleCloudStorage' + 'Greenplum' + 'Hbase' + 'Hdfs' + 'Hive' + 'Hubspot' + 'Impala' + 'Informix' + 'Jira' + 'Magento' + 'MariaDb' + 'Marketo' + 'MicrosoftAccess' + 'MongoDbAtlas' + 'MongoDbV2' + 'MySql' + 'Netezza' + 'ODataRest' + 'Odbc' + 'Office365' + 'OpenAI' + 'Oracle' + 'OracleCloudStorage' + 'OracleServiceCloud' + 'PayPal' + 'Phoenix' + 'PostgreSql' + 'Presto' + 'PythonFeed' + 'QuickBooks' + 'Redis' + 'Responsys' + 'S3' + 'Salesforce' + 'SalesforceMarketingCloud' + 'SalesforceServiceCloud' + 'SapBw' + 'SapCloudForCustomer' + 'SapEcc' + 'SapHana' + 'SapOpenHub' + 'SapTable' + 'Serp' + 'Serverless' + 'ServiceNow' + 'Sftp' + 'SharePointOnlineList' + 'Shopify' + 'Snowflake' + 'Spark' + 'SqlServer' + 'Square' + 'Sybase' + 'Teradata' + 'Vertica' + 'WebTable' + 'Xero' + 'Zoho' + ] + ``` + +### Parameter: `connectionProperties` + +The properties of the connection, specific to the auth type. + +- Required: Yes +- Type: secureObject + +### Parameter: `machineLearningWorkspaceName` + +The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `name` + +Name of the connection to create. + +- Required: Yes +- Type: string + +### Parameter: `target` + +The target of the connection. + +- Required: Yes +- Type: string + +### Parameter: `expiryTime` + +The expiry time of the connection. + +- Required: No +- Type: string + +### Parameter: `isSharedToAll` + +Indicates whether the connection is shared to all users in the workspace. + +- Required: No +- Type: bool + +### Parameter: `metadata` + +User metadata for the connection. + +- Required: No +- Type: object +- Default: `{}` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`>Any_other_property<`](#parameter-metadata>any_other_property<) | string | The metadata key-value pairs. | + +### Parameter: `metadata.>Any_other_property<` + +The metadata key-value pairs. + +- Required: Yes +- Type: string + +### Parameter: `sharedUserList` + +The shared user list of the connection. + +- Required: No +- Type: array + +### Parameter: `value` + +Value details of the workspace connection. + +- Required: No +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the connection. | +| `resourceGroupName` | string | The name of the resource group the connection was created in. | +| `resourceId` | string | The resource ID of the connection. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/machine-learning-services/workspace/connection/main.bicep b/avm/res/machine-learning-services/workspace/connection/main.bicep new file mode 100644 index 0000000000..0aeab2a4f7 --- /dev/null +++ b/avm/res/machine-learning-services/workspace/connection/main.bicep @@ -0,0 +1,393 @@ +metadata name = 'Machine Learning Services Workspaces Connections' +metadata description = 'This module creates a connection in a Machine Learning Services workspace.' +metadata owner = 'Azure/module-maintainers' + +// ================ // +// Parameters // +// ================ // + +@description('Required. Name of the connection to create.') +param name string + +@description('Required. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment.') +param machineLearningWorkspaceName string + +@description('Required. Category of the connection.') +param category categoryType + +@description('Optional. The expiry time of the connection.') +param expiryTime string? + +@description('Optional. Indicates whether the connection is shared to all users in the workspace.') +param isSharedToAll bool? + +@description('Optional. User metadata for the connection.') +param metadata metadataType = {} + +@description('Optional. The shared user list of the connection.') +param sharedUserList string[]? + +@description('Required. The target of the connection.') +param target string + +@description('Optional. Value details of the workspace connection.') +param value string? + +@description('Required. The properties of the connection, specific to the auth type.') +param connectionProperties connectionPropertyType + +// ============================= // +// Existing resources references // +// ============================= // + +resource machineLearningWorkspace 'Microsoft.MachineLearningServices/workspaces@2022-10-01' existing = { + name: machineLearningWorkspaceName +} + +// ============== // +// Resources // +// ============== // + +resource connection 'Microsoft.MachineLearningServices/workspaces/connections@2024-04-01' = { + name: name + parent: machineLearningWorkspace + properties: union( + { + category: category + expiryTime: expiryTime + isSharedToAll: isSharedToAll + metadata: metadata + sharedUserList: sharedUserList + target: target + value: value + }, + connectionProperties + ) +} + +// ============ // +// Outputs // +// ============ // + +@description('The resource ID of the connection.') +output resourceId string = connection.id + +@description('The name of the connection.') +output name string = connection.name + +@description('The name of the resource group the connection was created in.') +output resourceGroupName string = resourceGroup().name + +// ================ // +// Definitions // +// ================ // + +type metadataType = { + @description('Required. The metadata key-value pairs.') + *: string +} + +@export() +type categoryType = + | 'ADLSGen2' + | 'AIServices' + | 'AmazonMws' + | 'AmazonRdsForOracle' + | 'AmazonRdsForSqlServer' + | 'AmazonRedshift' + | 'AmazonS3Compatible' + | 'ApiKey' + | 'AzureBlob' + | 'AzureDataExplorer' + | 'AzureDatabricksDeltaLake' + | 'AzureMariaDb' + | 'AzureMySqlDb' + | 'AzureOneLake' + | 'AzureOpenAI' + | 'AzurePostgresDb' + | 'AzureSqlDb' + | 'AzureSqlMi' + | 'AzureSynapseAnalytics' + | 'AzureTableStorage' + | 'BingLLMSearch' + | 'Cassandra' + | 'CognitiveSearch' + | 'CognitiveService' + | 'Concur' + | 'ContainerRegistry' + | 'CosmosDb' + | 'CosmosDbMongoDbApi' + | 'Couchbase' + | 'CustomKeys' + | 'Db2' + | 'Drill' + | 'Dynamics' + | 'DynamicsAx' + | 'DynamicsCrm' + | 'Eloqua' + | 'FileServer' + | 'FtpServer' + | 'GenericContainerRegistry' + | 'GenericHttp' + | 'GenericRest' + | 'Git' + | 'GoogleAdWords' + | 'GoogleBigQuery' + | 'GoogleCloudStorage' + | 'Greenplum' + | 'Hbase' + | 'Hdfs' + | 'Hive' + | 'Hubspot' + | 'Impala' + | 'Informix' + | 'Jira' + | 'Magento' + | 'MariaDb' + | 'Marketo' + | 'MicrosoftAccess' + | 'MongoDbAtlas' + | 'MongoDbV2' + | 'MySql' + | 'Netezza' + | 'ODataRest' + | 'Odbc' + | 'Office365' + | 'OpenAI' + | 'Oracle' + | 'OracleCloudStorage' + | 'OracleServiceCloud' + | 'PayPal' + | 'Phoenix' + | 'PostgreSql' + | 'Presto' + | 'PythonFeed' + | 'QuickBooks' + | 'Redis' + | 'Responsys' + | 'S3' + | 'Salesforce' + | 'SalesforceMarketingCloud' + | 'SalesforceServiceCloud' + | 'SapBw' + | 'SapCloudForCustomer' + | 'SapEcc' + | 'SapHana' + | 'SapOpenHub' + | 'SapTable' + | 'Serp' + | 'Serverless' + | 'ServiceNow' + | 'Sftp' + | 'SharePointOnlineList' + | 'Shopify' + | 'Snowflake' + | 'Spark' + | 'SqlServer' + | 'Square' + | 'Sybase' + | 'Teradata' + | 'Vertica' + | 'WebTable' + | 'Xero' + | 'Zoho' + +type aadAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'AAD' +} + +type accessKeyAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'AccessKey' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionAccessKeyType +} + +type accountKeyAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'AccountKey' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionAccountKey +} + +type apiKeyAuthWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'ApiKey' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionApiKeyType +} + +type customKeysWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'CustomKeys' + + @description('Required. The credentials for the connection.') + credentials: customKeysType +} + +type managedIdentityAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'ManagedIdentity' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionManagedIdentityType +} + +type noneAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'None' +} + +type oauth2AuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'OAuth2' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionOAuth2Type +} + +type patAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'PAT' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionPersonalAccessTokenType +} + +type sasAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'SAS' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionSharedAccessSignatureType +} + +type servicePrincipalAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'ServicePrincipal' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionServicePrincipalType +} + +type usernamePasswordAuthTypeWorkspaceConnectionPropertyType = { + @description('Required. The authentication type of the connection target.') + authType: 'UsernamePassword' + + @description('Required. The credentials for the connection.') + credentials: workspaceConnectionUsernamePasswordType +} + +type customKeysType = { + @description('Required. The custom keys for the connection.') + keys: { + @description('Required. Key-value pairs for the custom keys.') + *: string + } +} + +type workspaceConnectionAccessKeyType = { + @description('Required. The connection access key ID.') + accessKeyId: string + + @description('Required. The connection secret access key.') + secretAccessKey: string +} + +type workspaceConnectionAccountKey = { + @description('Required. The connection key.') + key: string +} + +type workspaceConnectionApiKeyType = { + @description('Required. The connection API key.') + key: string +} + +type workspaceConnectionManagedIdentityType = { + @description('Required. The connection managed identity ID.') + clientId: string + + @description('Required. The connection managed identity resource ID.') + resourceId: string +} + +type workspaceConnectionOAuth2Type = { + @description('Conditional. The connection auth URL. Required by Concur connection category.') + authUrl: string? + + @minLength(36) + @maxLength(36) + @description('Required. The connection client ID in the format of UUID.') + clientId: string + + @description('Required. The connection client secret.') + clientSecret: string + + @description('Conditional. The connection developer token. Required by GoogleAdWords connection category.') + developerToken: string? + + @description('Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is \'Password\'.') + password: string? + + @description('Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories.') + refreshToken: string? + + @description('Required. The connection tenant ID. Required by QuickBooks and Xero connection categories.') + tenantId: string? + + @description('Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is \'Password\'.') + username: string? +} + +type workspaceConnectionPersonalAccessTokenType = { + @description('Required. The connection personal access token.') + pat: string +} + +type workspaceConnectionSharedAccessSignatureType = { + @description('Required. The connection SAS token.') + sas: string +} + +type workspaceConnectionServicePrincipalType = { + @description('Required. The connection client ID.') + clientId: string + + @description('Required. The connection client secret.') + clientSecret: string + + @description('Required. The connection tenant ID.') + tenantId: string +} + +type workspaceConnectionUsernamePasswordType = { + @description('Required. The connection password.') + password: string + + @description('Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to \'UsernamePassword\'.') + securityToken: string? + + @description('Required. The connection username.') + username: string +} + +@secure() +@export() +@discriminator('authType') +type connectionPropertyType = + | aadAuthTypeWorkspaceConnectionPropertyType + | accessKeyAuthTypeWorkspaceConnectionPropertyType + | apiKeyAuthWorkspaceConnectionPropertyType + | customKeysWorkspaceConnectionPropertyType + | managedIdentityAuthTypeWorkspaceConnectionPropertyType + | noneAuthTypeWorkspaceConnectionPropertyType + | oauth2AuthTypeWorkspaceConnectionPropertyType + | patAuthTypeWorkspaceConnectionPropertyType + | sasAuthTypeWorkspaceConnectionPropertyType + | servicePrincipalAuthTypeWorkspaceConnectionPropertyType + | usernamePasswordAuthTypeWorkspaceConnectionPropertyType diff --git a/avm/res/machine-learning-services/workspace/connection/main.json b/avm/res/machine-learning-services/workspace/connection/main.json new file mode 100644 index 0000000000..6e49f757aa --- /dev/null +++ b/avm/res/machine-learning-services/workspace/connection/main.json @@ -0,0 +1,723 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "2277907099827503661" + }, + "name": "Machine Learning Services Workspaces Connections", + "description": "This module creates a connection in a Machine Learning Services workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "metadataType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. The metadata key-value pairs." + } + } + }, + "categoryType": { + "type": "string", + "allowedValues": [ + "ADLSGen2", + "AIServices", + "AmazonMws", + "AmazonRdsForOracle", + "AmazonRdsForSqlServer", + "AmazonRedshift", + "AmazonS3Compatible", + "ApiKey", + "AzureBlob", + "AzureDataExplorer", + "AzureDatabricksDeltaLake", + "AzureMariaDb", + "AzureMySqlDb", + "AzureOneLake", + "AzureOpenAI", + "AzurePostgresDb", + "AzureSqlDb", + "AzureSqlMi", + "AzureSynapseAnalytics", + "AzureTableStorage", + "BingLLMSearch", + "Cassandra", + "CognitiveSearch", + "CognitiveService", + "Concur", + "ContainerRegistry", + "CosmosDb", + "CosmosDbMongoDbApi", + "Couchbase", + "CustomKeys", + "Db2", + "Drill", + "Dynamics", + "DynamicsAx", + "DynamicsCrm", + "Eloqua", + "FileServer", + "FtpServer", + "GenericContainerRegistry", + "GenericHttp", + "GenericRest", + "Git", + "GoogleAdWords", + "GoogleBigQuery", + "GoogleCloudStorage", + "Greenplum", + "Hbase", + "Hdfs", + "Hive", + "Hubspot", + "Impala", + "Informix", + "Jira", + "Magento", + "MariaDb", + "Marketo", + "MicrosoftAccess", + "MongoDbAtlas", + "MongoDbV2", + "MySql", + "Netezza", + "ODataRest", + "Odbc", + "Office365", + "OpenAI", + "Oracle", + "OracleCloudStorage", + "OracleServiceCloud", + "PayPal", + "Phoenix", + "PostgreSql", + "Presto", + "PythonFeed", + "QuickBooks", + "Redis", + "Responsys", + "S3", + "Salesforce", + "SalesforceMarketingCloud", + "SalesforceServiceCloud", + "SapBw", + "SapCloudForCustomer", + "SapEcc", + "SapHana", + "SapOpenHub", + "SapTable", + "Serp", + "Serverless", + "ServiceNow", + "Sftp", + "SharePointOnlineList", + "Shopify", + "Snowflake", + "Spark", + "SqlServer", + "Square", + "Sybase", + "Teradata", + "Vertica", + "WebTable", + "Xero", + "Zoho" + ], + "metadata": { + "__bicep_export!": true + } + }, + "aadAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AAD" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "accessKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccessKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccessKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "accountKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccountKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccountKey", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "apiKeyAuthWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ApiKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionApiKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "CustomKeys" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/customKeysType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "managedIdentityAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ManagedIdentity" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionManagedIdentityType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "noneAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "None" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "oauth2AuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "OAuth2" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionOAuth2Type", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "patAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "PAT" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionPersonalAccessTokenType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "sasAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "SAS" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionSharedAccessSignatureType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "servicePrincipalAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ServicePrincipal" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionServicePrincipalType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "usernamePasswordAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "UsernamePassword" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionUsernamePasswordType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysType": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. Key-value pairs for the custom keys." + } + }, + "metadata": { + "description": "Required. The custom keys for the connection." + } + } + } + }, + "workspaceConnectionAccessKeyType": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "metadata": { + "description": "Required. The connection access key ID." + } + }, + "secretAccessKey": { + "type": "string", + "metadata": { + "description": "Required. The connection secret access key." + } + } + } + }, + "workspaceConnectionAccountKey": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection key." + } + } + } + }, + "workspaceConnectionApiKeyType": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection API key." + } + } + } + }, + "workspaceConnectionManagedIdentityType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity ID." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity resource ID." + } + } + } + }, + "workspaceConnectionOAuth2Type": { + "type": "object", + "properties": { + "authUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection auth URL. Required by Concur connection category." + } + }, + "clientId": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Required. The connection client ID in the format of UUID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "developerToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection developer token. Required by GoogleAdWords connection category." + } + }, + "password": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + }, + "refreshToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The connection tenant ID. Required by QuickBooks and Xero connection categories." + } + }, + "username": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + } + } + }, + "workspaceConnectionPersonalAccessTokenType": { + "type": "object", + "properties": { + "pat": { + "type": "string", + "metadata": { + "description": "Required. The connection personal access token." + } + } + } + }, + "workspaceConnectionSharedAccessSignatureType": { + "type": "object", + "properties": { + "sas": { + "type": "string", + "metadata": { + "description": "Required. The connection SAS token." + } + } + } + }, + "workspaceConnectionServicePrincipalType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection client ID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The connection tenant ID." + } + } + } + }, + "workspaceConnectionUsernamePasswordType": { + "type": "object", + "properties": { + "password": { + "type": "string", + "metadata": { + "description": "Required. The connection password." + } + }, + "securityToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to 'UsernamePassword'." + } + }, + "username": { + "type": "string", + "metadata": { + "description": "Required. The connection username." + } + } + } + }, + "connectionPropertyType": { + "type": "secureObject", + "discriminator": { + "propertyName": "authType", + "mapping": { + "AAD": { + "$ref": "#/definitions/aadAuthTypeWorkspaceConnectionPropertyType" + }, + "AccessKey": { + "$ref": "#/definitions/accessKeyAuthTypeWorkspaceConnectionPropertyType" + }, + "ApiKey": { + "$ref": "#/definitions/apiKeyAuthWorkspaceConnectionPropertyType" + }, + "CustomKeys": { + "$ref": "#/definitions/customKeysWorkspaceConnectionPropertyType" + }, + "ManagedIdentity": { + "$ref": "#/definitions/managedIdentityAuthTypeWorkspaceConnectionPropertyType" + }, + "None": { + "$ref": "#/definitions/noneAuthTypeWorkspaceConnectionPropertyType" + }, + "OAuth2": { + "$ref": "#/definitions/oauth2AuthTypeWorkspaceConnectionPropertyType" + }, + "PAT": { + "$ref": "#/definitions/patAuthTypeWorkspaceConnectionPropertyType" + }, + "SAS": { + "$ref": "#/definitions/sasAuthTypeWorkspaceConnectionPropertyType" + }, + "ServicePrincipal": { + "$ref": "#/definitions/servicePrincipalAuthTypeWorkspaceConnectionPropertyType" + }, + "UsernamePassword": { + "$ref": "#/definitions/usernamePasswordAuthTypeWorkspaceConnectionPropertyType" + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the connection to create." + } + }, + "machineLearningWorkspaceName": { + "type": "string", + "metadata": { + "description": "Required. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." + } + }, + "category": { + "$ref": "#/definitions/categoryType", + "metadata": { + "description": "Required. Category of the connection." + } + }, + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiry time of the connection." + } + }, + "isSharedToAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether the connection is shared to all users in the workspace." + } + }, + "metadata": { + "$ref": "#/definitions/metadataType", + "defaultValue": {}, + "metadata": { + "description": "Optional. User metadata for the connection." + } + }, + "sharedUserList": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The shared user list of the connection." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Required. The target of the connection." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Value details of the workspace connection." + } + }, + "connectionProperties": { + "$ref": "#/definitions/connectionPropertyType", + "metadata": { + "description": "Required. The properties of the connection, specific to the auth type." + } + } + }, + "resources": { + "machineLearningWorkspace": { + "existing": true, + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('machineLearningWorkspaceName')]" + }, + "connection": { + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01", + "name": "[format('{0}/{1}', parameters('machineLearningWorkspaceName'), parameters('name'))]", + "properties": "[union(createObject('category', parameters('category'), 'expiryTime', parameters('expiryTime'), 'isSharedToAll', parameters('isSharedToAll'), 'metadata', parameters('metadata'), 'sharedUserList', parameters('sharedUserList'), 'target', parameters('target'), 'value', parameters('value')), parameters('connectionProperties'))]", + "dependsOn": [ + "machineLearningWorkspace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the connection." + }, + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/connections', parameters('machineLearningWorkspaceName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the connection." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the connection was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/machine-learning-services/workspace/main.bicep b/avm/res/machine-learning-services/workspace/main.bicep index 572f03195a..6ff05fed5f 100644 --- a/avm/res/machine-learning-services/workspace/main.bicep +++ b/avm/res/machine-learning-services/workspace/main.bicep @@ -59,6 +59,9 @@ param privateEndpoints privateEndpointType @sys.description('Optional. Computes to create respectively attach to the workspace.') param computes array? +@sys.description('Optional. Connections to create in the workspace.') +param connections connectionType[] = [] + @sys.description('Optional. Resource tags.') param tags object? @@ -306,6 +309,24 @@ module workspace_computes 'compute/main.bicep' = [ } ] +module workspace_connections 'connection/main.bicep' = [ + for connection in connections: { + name: '${workspace.name}-${connection.name}-connection' + params: { + machineLearningWorkspaceName: workspace.name + name: connection.name + category: connection.category + expiryTime: connection.?expiryTime + isSharedToAll: connection.?isSharedToAll + metadata: connection.?metadata + sharedUserList: connection.?sharedUserList + target: connection.target + value: connection.?value + connectionProperties: connection.connectionProperties + } + } +] + resource workspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' properties: { @@ -718,3 +739,37 @@ type customerManagedKeyType = { @sys.description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') userAssignedIdentityResourceId: string? }? + +import { categoryType, connectionPropertyType } from 'connection/main.bicep' + +type connectionType = { + @sys.description('Required. Name of the connection to create.') + name: string + + @sys.description('Required. Category of the connection.') + category: categoryType + + @sys.description('Optional. The expiry time of the connection.') + expiryTime: string? + + @sys.description('Optional. Indicates whether the connection is shared to all users in the workspace.') + isSharedToAll: bool? + + @sys.description('Optional. User metadata for the connection.') + metadata: { + @sys.description('Required. The metadata key-value pairs.') + *: string + }? + + @sys.description('Optional. The shared user list of the connection.') + sharedUserList: string[]? + + @sys.description('Required. The target of the connection.') + target: string + + @sys.description('Optional. Value details of the workspace connection.') + value: string? + + @sys.description('Required. The properties of the connection, specific to the auth type.') + connectionProperties: connectionPropertyType +} diff --git a/avm/res/machine-learning-services/workspace/main.json b/avm/res/machine-learning-services/workspace/main.json index d41096dcad..883c30b6d7 100644 --- a/avm/res/machine-learning-services/workspace/main.json +++ b/avm/res/machine-learning-services/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8690832588645488864" + "templateHash": "3070187757867486541" }, "name": "Machine Learning Services Workspaces", "description": "This module deploys a Machine Learning Services Workspace.", @@ -777,233 +777,976 @@ } }, "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the machine learning workspace." - } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." + "connectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the connection to create." + } + }, + "category": { + "$ref": "#/definitions/categoryType", + "metadata": { + "description": "Required. Category of the connection." + } + }, + "expiryTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The expiry time of the connection." + } + }, + "isSharedToAll": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Indicates whether the connection is shared to all users in the workspace." + } + }, + "metadata": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. The metadata key-value pairs." + } + }, + "nullable": true, + "metadata": { + "description": "Optional. User metadata for the connection." + } + }, + "sharedUserList": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The shared user list of the connection." + } + }, + "target": { + "type": "string", + "metadata": { + "description": "Required. The target of the connection." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Value details of the workspace connection." + } + }, + "connectionProperties": { + "$ref": "#/definitions/connectionPropertyType", + "metadata": { + "description": "Required. The properties of the connection, specific to the auth type." + } + } } }, - "sku": { - "type": "string", - "allowedValues": [ - "Free", - "Basic", - "Standard", - "Premium" - ], + "_1.aadAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AAD" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + }, "metadata": { - "description": "Required. Specifies the SKU, also referred as 'edition' of the Azure Machine Learning workspace." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "kind": { - "type": "string", - "defaultValue": "Default", - "allowedValues": [ - "Default", - "Project", - "Hub", - "FeatureStore" - ], + "_1.accessKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccessKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionAccessKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. The type of Azure Machine Learning workspace to create." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "associatedStorageAccountResourceId": { - "type": "string", - "nullable": true, + "_1.apiKeyAuthWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ApiKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionApiKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Conditional. The resource ID of the associated Storage Account. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "associatedKeyVaultResourceId": { - "type": "string", - "nullable": true, + "_1.customKeysType": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. Key-value pairs for the custom keys." + } + }, + "metadata": { + "description": "Required. The custom keys for the connection." + } + } + }, "metadata": { - "description": "Conditional. The resource ID of the associated Key Vault. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "associatedApplicationInsightsResourceId": { - "type": "string", - "nullable": true, + "_1.customKeysWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "CustomKeys" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.customKeysType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Conditional. The resource ID of the associated Application Insights. Required if 'kind' is 'Default' or 'FeatureStore'." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "associatedContainerRegistryResourceId": { - "type": "string", - "nullable": true, + "_1.managedIdentityAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ManagedIdentity" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionManagedIdentityType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. The resource ID of the associated Container Registry." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "lock": { - "$ref": "#/definitions/lockType", + "_1.noneAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "None" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + }, "metadata": { - "description": "Optional. The lock settings of the service." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "hbiWorkspace": { - "type": "bool", - "defaultValue": false, + "_1.oauth2AuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "OAuth2" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionOAuth2Type", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. The flag to signal HBI data in the workspace and reduce diagnostic data collected by the service." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "hubResourceId": { - "type": "string", - "nullable": true, + "_1.patAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "PAT" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionPersonalAccessTokenType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Conditional. The resource ID of the hub to associate with the workspace. Required if 'kind' is set to 'Project'." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "_1.sasAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "SAS" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionSharedAccessSignatureType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. Array of role assignments to create." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "_1.servicePrincipalAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ServicePrincipal" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionServicePrincipalType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "computes": { - "type": "array", - "nullable": true, + "_1.usernamePasswordAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "UsernamePassword" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/_1.workspaceConnectionUsernamePasswordType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + }, "metadata": { - "description": "Optional. Computes to create respectively attach to the workspace." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "tags": { + "_1.workspaceConnectionAccessKeyType": { "type": "object", - "nullable": true, + "properties": { + "accessKeyId": { + "type": "string", + "metadata": { + "description": "Required. The connection access key ID." + } + }, + "secretAccessKey": { + "type": "string", + "metadata": { + "description": "Required. The connection secret access key." + } + } + }, "metadata": { - "description": "Optional. Resource tags." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, + "_1.workspaceConnectionApiKeyType": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection API key." + } + } + }, "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", - "defaultValue": { - "systemAssigned": true + "_1.workspaceConnectionManagedIdentityType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity ID." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity resource ID." + } + } }, "metadata": { - "description": "Optional. The managed identity definition for this resource. At least one identity type is required." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "featureStoreSettings": { - "$ref": "#/definitions/featureStoreSettingType", + "_1.workspaceConnectionOAuth2Type": { + "type": "object", + "properties": { + "authUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection auth URL. Required by Concur connection category." + } + }, + "clientId": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Required. The connection client ID in the format of UUID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "developerToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection developer token. Required by GoogleAdWords connection category." + } + }, + "password": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + }, + "refreshToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The connection tenant ID. Required by QuickBooks and Xero connection categories." + } + }, + "username": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + } + }, "metadata": { - "description": "Conditional. Settings for feature store type workspaces. Required if 'kind' is set to 'FeatureStore'." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "managedNetworkSettings": { - "$ref": "#/definitions/managedNetworkSettingType", + "_1.workspaceConnectionPersonalAccessTokenType": { + "type": "object", + "properties": { + "pat": { + "type": "string", + "metadata": { + "description": "Required. The connection personal access token." + } + } + }, "metadata": { - "description": "Optional. Managed Network settings for a machine learning workspace." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "serverlessComputeSettings": { - "$ref": "#/definitions/serverlessComputeSettingType", + "_1.workspaceConnectionServicePrincipalType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection client ID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The connection tenant ID." + } + } + }, "metadata": { - "description": "Optional. Settings for serverless compute created in the workspace." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "systemDatastoresAuthMode": { + "_1.workspaceConnectionSharedAccessSignatureType": { + "type": "object", + "properties": { + "sas": { + "type": "string", + "metadata": { + "description": "Required. The connection SAS token." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "_1.workspaceConnectionUsernamePasswordType": { + "type": "object", + "properties": { + "password": { + "type": "string", + "metadata": { + "description": "Required. The connection password." + } + }, + "securityToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to 'UsernamePassword'." + } + }, + "username": { + "type": "string", + "metadata": { + "description": "Required. The connection username." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } + } + }, + "categoryType": { "type": "string", - "nullable": true, "allowedValues": [ - "accessKey", - "identity" + "ADLSGen2", + "AIServices", + "AmazonMws", + "AmazonRdsForOracle", + "AmazonRdsForSqlServer", + "AmazonRedshift", + "AmazonS3Compatible", + "ApiKey", + "AzureBlob", + "AzureDataExplorer", + "AzureDatabricksDeltaLake", + "AzureMariaDb", + "AzureMySqlDb", + "AzureOneLake", + "AzureOpenAI", + "AzurePostgresDb", + "AzureSqlDb", + "AzureSqlMi", + "AzureSynapseAnalytics", + "AzureTableStorage", + "BingLLMSearch", + "Cassandra", + "CognitiveSearch", + "CognitiveService", + "Concur", + "ContainerRegistry", + "CosmosDb", + "CosmosDbMongoDbApi", + "Couchbase", + "CustomKeys", + "Db2", + "Drill", + "Dynamics", + "DynamicsAx", + "DynamicsCrm", + "Eloqua", + "FileServer", + "FtpServer", + "GenericContainerRegistry", + "GenericHttp", + "GenericRest", + "Git", + "GoogleAdWords", + "GoogleBigQuery", + "GoogleCloudStorage", + "Greenplum", + "Hbase", + "Hdfs", + "Hive", + "Hubspot", + "Impala", + "Informix", + "Jira", + "Magento", + "MariaDb", + "Marketo", + "MicrosoftAccess", + "MongoDbAtlas", + "MongoDbV2", + "MySql", + "Netezza", + "ODataRest", + "Odbc", + "Office365", + "OpenAI", + "Oracle", + "OracleCloudStorage", + "OracleServiceCloud", + "PayPal", + "Phoenix", + "PostgreSql", + "Presto", + "PythonFeed", + "QuickBooks", + "Redis", + "Responsys", + "S3", + "Salesforce", + "SalesforceMarketingCloud", + "SalesforceServiceCloud", + "SapBw", + "SapCloudForCustomer", + "SapEcc", + "SapHana", + "SapOpenHub", + "SapTable", + "Serp", + "Serverless", + "ServiceNow", + "Sftp", + "SharePointOnlineList", + "Shopify", + "Snowflake", + "Spark", + "SqlServer", + "Square", + "Sybase", + "Teradata", + "Vertica", + "WebTable", + "Xero", + "Zoho" ], "metadata": { - "description": "Optional. The authentication mode used by the workspace when connecting to the default storage account." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } }, - "workspaceHubConfig": { - "$ref": "#/definitions/workspaceHubConfigType", + "connectionPropertyType": { + "type": "secureObject", + "discriminator": { + "propertyName": "authType", + "mapping": { + "AAD": { + "$ref": "#/definitions/_1.aadAuthTypeWorkspaceConnectionPropertyType" + }, + "AccessKey": { + "$ref": "#/definitions/_1.accessKeyAuthTypeWorkspaceConnectionPropertyType" + }, + "ApiKey": { + "$ref": "#/definitions/_1.apiKeyAuthWorkspaceConnectionPropertyType" + }, + "CustomKeys": { + "$ref": "#/definitions/_1.customKeysWorkspaceConnectionPropertyType" + }, + "ManagedIdentity": { + "$ref": "#/definitions/_1.managedIdentityAuthTypeWorkspaceConnectionPropertyType" + }, + "None": { + "$ref": "#/definitions/_1.noneAuthTypeWorkspaceConnectionPropertyType" + }, + "OAuth2": { + "$ref": "#/definitions/_1.oauth2AuthTypeWorkspaceConnectionPropertyType" + }, + "PAT": { + "$ref": "#/definitions/_1.patAuthTypeWorkspaceConnectionPropertyType" + }, + "SAS": { + "$ref": "#/definitions/_1.sasAuthTypeWorkspaceConnectionPropertyType" + }, + "ServicePrincipal": { + "$ref": "#/definitions/_1.servicePrincipalAuthTypeWorkspaceConnectionPropertyType" + }, + "UsernamePassword": { + "$ref": "#/definitions/_1.usernamePasswordAuthTypeWorkspaceConnectionPropertyType" + } + } + }, "metadata": { - "description": "Optional. Configuration for workspace hub settings." + "__bicep_imported_from!": { + "sourceTemplate": "connection/main.bicep" + } } - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + } + }, + "parameters": { + "name": { + "type": "string", "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Required. The name of the machine learning workspace." } }, - "description": { + "location": { "type": "string", - "nullable": true, + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. The description of this workspace." + "description": "Optional. Location for all resources." } }, - "discoveryUrl": { + "sku": { "type": "string", - "nullable": true, + "allowedValues": [ + "Free", + "Basic", + "Standard", + "Premium" + ], "metadata": { - "description": "Optional. URL for the discovery service to identify regional endpoints for machine learning experimentation services." + "description": "Required. Specifies the SKU, also referred as 'edition' of the Azure Machine Learning workspace." } }, - "customerManagedKey": { - "$ref": "#/definitions/customerManagedKeyType", + "kind": { + "type": "string", + "defaultValue": "Default", + "allowedValues": [ + "Default", + "Project", + "Hub", + "FeatureStore" + ], "metadata": { - "description": "Optional. The customer managed key definition." + "description": "Optional. The type of Azure Machine Learning workspace to create." } }, - "imageBuildCompute": { + "associatedStorageAccountResourceId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The compute name for image build." + "description": "Conditional. The resource ID of the associated Storage Account. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." } }, - "primaryUserAssignedIdentity": { + "associatedKeyVaultResourceId": { "type": "string", "nullable": true, "metadata": { - "description": "Conditional. The user assigned identity resource ID that represents the workspace identity. Required if 'userAssignedIdentities' is not empty and may not be used if 'systemAssignedIdentity' is enabled." + "description": "Conditional. The resource ID of the associated Key Vault. Required if 'kind' is 'Default', 'FeatureStore' or 'Hub'." } }, - "serviceManagedResourcesSettings": { - "type": "object", + "associatedApplicationInsightsResourceId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The service managed resource settings." + "description": "Conditional. The resource ID of the associated Application Insights. Required if 'kind' is 'Default' or 'FeatureStore'." } }, - "sharedPrivateLinkResources": { - "type": "array", + "associatedContainerRegistryResourceId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The list of shared private link resources in this workspace. Note: This property is not idempotent." + "description": "Optional. The resource ID of the associated Container Registry." } }, - "publicNetworkAccess": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Enabled", - "Disabled" - ], + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "hbiWorkspace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag to signal HBI data in the workspace and reduce diagnostic data collected by the service." + } + }, + "hubResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The resource ID of the hub to associate with the workspace. Required if 'kind' is set to 'Project'." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "computes": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Computes to create respectively attach to the workspace." + } + }, + "connections": { + "type": "array", + "items": { + "$ref": "#/definitions/connectionType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Connections to create in the workspace." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "defaultValue": { + "systemAssigned": true + }, + "metadata": { + "description": "Optional. The managed identity definition for this resource. At least one identity type is required." + } + }, + "featureStoreSettings": { + "$ref": "#/definitions/featureStoreSettingType", + "metadata": { + "description": "Conditional. Settings for feature store type workspaces. Required if 'kind' is set to 'FeatureStore'." + } + }, + "managedNetworkSettings": { + "$ref": "#/definitions/managedNetworkSettingType", + "metadata": { + "description": "Optional. Managed Network settings for a machine learning workspace." + } + }, + "serverlessComputeSettings": { + "$ref": "#/definitions/serverlessComputeSettingType", + "metadata": { + "description": "Optional. Settings for serverless compute created in the workspace." + } + }, + "systemDatastoresAuthMode": { + "type": "string", + "nullable": true, + "allowedValues": [ + "accessKey", + "identity" + ], + "metadata": { + "description": "Optional. The authentication mode used by the workspace when connecting to the default storage account." + } + }, + "workspaceHubConfig": { + "$ref": "#/definitions/workspaceHubConfigType", + "metadata": { + "description": "Optional. Configuration for workspace hub settings." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of this workspace." + } + }, + "discoveryUrl": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. URL for the discovery service to identify regional endpoints for machine learning experimentation services." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "imageBuildCompute": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The compute name for image build." + } + }, + "primaryUserAssignedIdentity": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The user assigned identity resource ID that represents the workspace identity. Required if 'userAssignedIdentities' is not empty and may not be used if 'systemAssignedIdentity' is enabled." + } + }, + "serviceManagedResourcesSettings": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The service managed resource settings." + } + }, + "sharedPrivateLinkResources": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The list of shared private link resources in this workspace. Note: This property is not idempotent." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], "metadata": { "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled." } @@ -1143,48 +1886,320 @@ "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" } } - ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "workspace" - ] - }, - "workspace_roleAssignments": { - "copy": { - "name": "workspace_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.MachineLearningServices/workspaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", - "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_roleAssignments": { + "copy": { + "name": "workspace_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.MachineLearningServices/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.MachineLearningServices/workspaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_computes": { + "copy": { + "name": "workspace_computes", + "count": "[length(coalesce(parameters('computes'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}-compute', parameters('name'), coalesce(parameters('computes'), createArray())[copyIndex()].name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "machineLearningWorkspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].name]" + }, + "location": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].location]" + }, + "sku": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'sku')]" + }, + "managedIdentities": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'managedIdentities')]" + }, + "tags": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'tags')]" + }, + "deployCompute": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'deployCompute')]" + }, + "computeLocation": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'computeLocation')]" + }, + "description": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'description')]" + }, + "disableLocalAuth": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'disableLocalAuth')]" + }, + "resourceId": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'resourceId')]" + }, + "computeType": { + "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].computeType]" + }, + "properties": { + "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'properties')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "8580750401363518569" + }, + "name": "Machine Learning Services Workspaces Computes", + "description": "This module deploys a Machine Learning Services Workspaces Compute.\n\nAttaching a compute is not idempotent and will fail in case you try to redeploy over an existing compute in AML (see parameter `deployCompute`).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + } + }, + "parameters": { + "machineLearningWorkspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "minLength": 2, + "maxLength": 16, + "metadata": { + "description": "Required. Name of the compute." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Specifies the location of the resource." + } + }, + "sku": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Basic", + "Free", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Specifies the sku, also referred as \"edition\". Required for creating a compute resource." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Contains resource tags defined as key-value pairs. Ignored when attaching a compute resource, i.e. when you provide a resource ID." + } + }, + "deployCompute": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Flag to specify whether to deploy the compute. Required only for attach (i.e. providing a resource ID), as in this case the operation is not idempotent, i.e. a second deployment will fail. Therefore, this flag needs to be set to \"false\" as long as the compute resource exists." + } + }, + "computeLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for the underlying compute. Ignored when attaching a compute resource, i.e. when you provide a resource ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the Machine Learning compute." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Opt-out of local authentication and ensure customers can use only MSI and AAD exclusively for authentication." + } + }, + "resourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ARM resource ID of the underlying compute." + } + }, + "computeType": { + "type": "string", + "allowedValues": [ + "AKS", + "AmlCompute", + "ComputeInstance", + "Databricks", + "DataFactory", + "DataLakeAnalytics", + "HDInsight", + "Kubernetes", + "SynapseSpark", + "VirtualMachine" + ], + "metadata": { + "description": "Required. Set the object type." + } + }, + "properties": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The properties of the compute. Will be ignored in case \"resourceId\" is set." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + } + }, + "variables": { + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" + }, + "resources": { + "machineLearningWorkspace": { + "existing": true, + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2022-10-01", + "name": "[parameters('machineLearningWorkspaceName')]" + }, + "compute": { + "condition": "[equals(parameters('deployCompute'), true())]", + "type": "Microsoft.MachineLearningServices/workspaces/computes", + "apiVersion": "2022-10-01", + "name": "[format('{0}/{1}', parameters('machineLearningWorkspaceName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[if(empty(parameters('resourceId')), parameters('tags'), null())]", + "sku": "[if(empty(parameters('resourceId')), createObject('name', parameters('sku'), 'tier', parameters('sku')), null())]", + "identity": "[if(empty(parameters('resourceId')), variables('identity'), null())]", + "properties": "[union(createObject('description', parameters('description'), 'disableLocalAuth', parameters('disableLocalAuth'), 'computeType', parameters('computeType')), if(not(empty(parameters('resourceId'))), createObject('resourceId', parameters('resourceId')), createObject('computeLocation', parameters('computeLocation'), 'properties', parameters('properties'))))]", + "dependsOn": [ + "machineLearningWorkspace" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the compute." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the compute." + }, + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/computes', parameters('machineLearningWorkspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the compute was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('compute', '2022-10-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('compute', '2022-10-01', 'full').location]" + } + } + } }, "dependsOn": [ - "workspace" + "workspace", + "workspace_privateEndpoints" ] }, - "workspace_computes": { + "workspace_connections": { "copy": { - "name": "workspace_computes", - "count": "[length(coalesce(parameters('computes'), createArray()))]" + "name": "workspace_connections", + "count": "[length(parameters('connections'))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}-compute', parameters('name'), coalesce(parameters('computes'), createArray())[copyIndex()].name)]", + "name": "[format('{0}-{1}-connection', parameters('name'), parameters('connections')[copyIndex()].name)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1195,40 +2210,31 @@ "value": "[parameters('name')]" }, "name": { - "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].name]" - }, - "location": { - "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].location]" - }, - "sku": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'sku')]" + "value": "[parameters('connections')[copyIndex()].name]" }, - "managedIdentities": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'managedIdentities')]" - }, - "tags": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'tags')]" + "category": { + "value": "[parameters('connections')[copyIndex()].category]" }, - "deployCompute": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'deployCompute')]" + "expiryTime": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'expiryTime')]" }, - "computeLocation": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'computeLocation')]" + "isSharedToAll": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'isSharedToAll')]" }, - "description": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'description')]" + "metadata": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'metadata')]" }, - "disableLocalAuth": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'disableLocalAuth')]" + "sharedUserList": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'sharedUserList')]" }, - "resourceId": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'resourceId')]" + "target": { + "value": "[parameters('connections')[copyIndex()].target]" }, - "computeType": { - "value": "[coalesce(parameters('computes'), createArray())[copyIndex()].computeType]" + "value": { + "value": "[tryGet(parameters('connections')[copyIndex()], 'value')]" }, - "properties": { - "value": "[tryGet(coalesce(parameters('computes'), createArray())[copyIndex()], 'properties')]" + "connectionProperties": { + "value": "[parameters('connections')[copyIndex()].connectionProperties]" } }, "template": { @@ -1239,150 +2245,680 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8580750401363518569" + "templateHash": "2277907099827503661" + }, + "name": "Machine Learning Services Workspaces Connections", + "description": "This module creates a connection in a Machine Learning Services workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "metadataType": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. The metadata key-value pairs." + } + } + }, + "categoryType": { + "type": "string", + "allowedValues": [ + "ADLSGen2", + "AIServices", + "AmazonMws", + "AmazonRdsForOracle", + "AmazonRdsForSqlServer", + "AmazonRedshift", + "AmazonS3Compatible", + "ApiKey", + "AzureBlob", + "AzureDataExplorer", + "AzureDatabricksDeltaLake", + "AzureMariaDb", + "AzureMySqlDb", + "AzureOneLake", + "AzureOpenAI", + "AzurePostgresDb", + "AzureSqlDb", + "AzureSqlMi", + "AzureSynapseAnalytics", + "AzureTableStorage", + "BingLLMSearch", + "Cassandra", + "CognitiveSearch", + "CognitiveService", + "Concur", + "ContainerRegistry", + "CosmosDb", + "CosmosDbMongoDbApi", + "Couchbase", + "CustomKeys", + "Db2", + "Drill", + "Dynamics", + "DynamicsAx", + "DynamicsCrm", + "Eloqua", + "FileServer", + "FtpServer", + "GenericContainerRegistry", + "GenericHttp", + "GenericRest", + "Git", + "GoogleAdWords", + "GoogleBigQuery", + "GoogleCloudStorage", + "Greenplum", + "Hbase", + "Hdfs", + "Hive", + "Hubspot", + "Impala", + "Informix", + "Jira", + "Magento", + "MariaDb", + "Marketo", + "MicrosoftAccess", + "MongoDbAtlas", + "MongoDbV2", + "MySql", + "Netezza", + "ODataRest", + "Odbc", + "Office365", + "OpenAI", + "Oracle", + "OracleCloudStorage", + "OracleServiceCloud", + "PayPal", + "Phoenix", + "PostgreSql", + "Presto", + "PythonFeed", + "QuickBooks", + "Redis", + "Responsys", + "S3", + "Salesforce", + "SalesforceMarketingCloud", + "SalesforceServiceCloud", + "SapBw", + "SapCloudForCustomer", + "SapEcc", + "SapHana", + "SapOpenHub", + "SapTable", + "Serp", + "Serverless", + "ServiceNow", + "Sftp", + "SharePointOnlineList", + "Shopify", + "Snowflake", + "Spark", + "SqlServer", + "Square", + "Sybase", + "Teradata", + "Vertica", + "WebTable", + "Xero", + "Zoho" + ], + "metadata": { + "__bicep_export!": true + } + }, + "aadAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AAD" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "accessKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccessKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccessKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "accountKeyAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "AccountKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionAccountKey", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "apiKeyAuthWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ApiKey" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionApiKeyType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "CustomKeys" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/customKeysType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "managedIdentityAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ManagedIdentity" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionManagedIdentityType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "noneAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "None" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + } + } + }, + "oauth2AuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "OAuth2" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionOAuth2Type", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "patAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "PAT" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionPersonalAccessTokenType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "sasAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "SAS" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionSharedAccessSignatureType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "servicePrincipalAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "ServicePrincipal" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionServicePrincipalType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "usernamePasswordAuthTypeWorkspaceConnectionPropertyType": { + "type": "object", + "properties": { + "authType": { + "type": "string", + "allowedValues": [ + "UsernamePassword" + ], + "metadata": { + "description": "Required. The authentication type of the connection target." + } + }, + "credentials": { + "$ref": "#/definitions/workspaceConnectionUsernamePasswordType", + "metadata": { + "description": "Required. The credentials for the connection." + } + } + } + }, + "customKeysType": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "properties": {}, + "additionalProperties": { + "type": "string", + "metadata": { + "description": "Required. Key-value pairs for the custom keys." + } + }, + "metadata": { + "description": "Required. The custom keys for the connection." + } + } + } + }, + "workspaceConnectionAccessKeyType": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "metadata": { + "description": "Required. The connection access key ID." + } + }, + "secretAccessKey": { + "type": "string", + "metadata": { + "description": "Required. The connection secret access key." + } + } + } }, - "name": "Machine Learning Services Workspaces Computes", - "description": "This module deploys a Machine Learning Services Workspaces Compute.\n\nAttaching a compute is not idempotent and will fail in case you try to redeploy over an existing compute in AML (see parameter `deployCompute`).", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "managedIdentitiesType": { + "workspaceConnectionAccountKey": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection key." + } + } + } + }, + "workspaceConnectionApiKeyType": { + "type": "object", + "properties": { + "key": { + "type": "string", + "metadata": { + "description": "Required. The connection API key." + } + } + } + }, + "workspaceConnectionManagedIdentityType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity ID." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The connection managed identity resource ID." + } + } + } + }, + "workspaceConnectionOAuth2Type": { + "type": "object", + "properties": { + "authUrl": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "Conditional. The connection auth URL. Required by Concur connection category." } }, - "userAssignedResourceIds": { - "type": "array", - "items": { - "type": "string" - }, + "clientId": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "metadata": { + "description": "Required. The connection client ID in the format of UUID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "developerToken": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Conditional. The connection developer token. Required by GoogleAdWords connection category." + } + }, + "password": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection password. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + }, + "refreshToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection refresh token. Required by GoogleBigQuery, GoogleAdWords, Hubspot, QuickBooks, Square, Xero and Zoho connection categories." + } + }, + "tenantId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The connection tenant ID. Required by QuickBooks and Xero connection categories." + } + }, + "username": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection username. Required by Concur and ServiceNow connection categories where AccessToken grant type is 'Password'." + } + } + } + }, + "workspaceConnectionPersonalAccessTokenType": { + "type": "object", + "properties": { + "pat": { + "type": "string", + "metadata": { + "description": "Required. The connection personal access token." + } + } + } + }, + "workspaceConnectionSharedAccessSignatureType": { + "type": "object", + "properties": { + "sas": { + "type": "string", + "metadata": { + "description": "Required. The connection SAS token." + } + } + } + }, + "workspaceConnectionServicePrincipalType": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. The connection client ID." + } + }, + "clientSecret": { + "type": "string", + "metadata": { + "description": "Required. The connection client secret." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "Required. The connection tenant ID." + } + } + } + }, + "workspaceConnectionUsernamePasswordType": { + "type": "object", + "properties": { + "password": { + "type": "string", + "metadata": { + "description": "Required. The connection password." + } + }, + "securityToken": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Conditional. The connection security token. Required by connections like SalesForce for extra security in addition to 'UsernamePassword'." + } + }, + "username": { + "type": "string", + "metadata": { + "description": "Required. The connection username." + } + } + } + }, + "connectionPropertyType": { + "type": "secureObject", + "discriminator": { + "propertyName": "authType", + "mapping": { + "AAD": { + "$ref": "#/definitions/aadAuthTypeWorkspaceConnectionPropertyType" + }, + "AccessKey": { + "$ref": "#/definitions/accessKeyAuthTypeWorkspaceConnectionPropertyType" + }, + "ApiKey": { + "$ref": "#/definitions/apiKeyAuthWorkspaceConnectionPropertyType" + }, + "CustomKeys": { + "$ref": "#/definitions/customKeysWorkspaceConnectionPropertyType" + }, + "ManagedIdentity": { + "$ref": "#/definitions/managedIdentityAuthTypeWorkspaceConnectionPropertyType" + }, + "None": { + "$ref": "#/definitions/noneAuthTypeWorkspaceConnectionPropertyType" + }, + "OAuth2": { + "$ref": "#/definitions/oauth2AuthTypeWorkspaceConnectionPropertyType" + }, + "PAT": { + "$ref": "#/definitions/patAuthTypeWorkspaceConnectionPropertyType" + }, + "SAS": { + "$ref": "#/definitions/sasAuthTypeWorkspaceConnectionPropertyType" + }, + "ServicePrincipal": { + "$ref": "#/definitions/servicePrincipalAuthTypeWorkspaceConnectionPropertyType" + }, + "UsernamePassword": { + "$ref": "#/definitions/usernamePasswordAuthTypeWorkspaceConnectionPropertyType" } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } } }, "parameters": { - "machineLearningWorkspaceName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." - } - }, "name": { "type": "string", - "minLength": 2, - "maxLength": 16, "metadata": { - "description": "Required. Name of the compute." + "description": "Required. Name of the connection to create." } }, - "location": { + "machineLearningWorkspaceName": { "type": "string", - "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Specifies the location of the resource." + "description": "Required. The name of the parent Machine Learning Workspace. Required if the template is used in a standalone deployment." } }, - "sku": { - "type": "string", - "nullable": true, - "allowedValues": [ - "Basic", - "Free", - "Premium", - "Standard" - ], + "category": { + "$ref": "#/definitions/categoryType", "metadata": { - "description": "Optional. Specifies the sku, also referred as \"edition\". Required for creating a compute resource." + "description": "Required. Category of the connection." } }, - "tags": { - "type": "object", + "expiryTime": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Contains resource tags defined as key-value pairs. Ignored when attaching a compute resource, i.e. when you provide a resource ID." + "description": "Optional. The expiry time of the connection." } }, - "deployCompute": { + "isSharedToAll": { "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Flag to specify whether to deploy the compute. Required only for attach (i.e. providing a resource ID), as in this case the operation is not idempotent, i.e. a second deployment will fail. Therefore, this flag needs to be set to \"false\" as long as the compute resource exists." - } - }, - "computeLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for the underlying compute. Ignored when attaching a compute resource, i.e. when you provide a resource ID." - } - }, - "description": { - "type": "string", "nullable": true, "metadata": { - "description": "Optional. The description of the Machine Learning compute." + "description": "Optional. Indicates whether the connection is shared to all users in the workspace." } }, - "disableLocalAuth": { - "type": "bool", - "defaultValue": false, + "metadata": { + "$ref": "#/definitions/metadataType", + "defaultValue": {}, "metadata": { - "description": "Optional. Opt-out of local authentication and ensure customers can use only MSI and AAD exclusively for authentication." + "description": "Optional. User metadata for the connection." } }, - "resourceId": { - "type": "string", + "sharedUserList": { + "type": "array", + "items": { + "type": "string" + }, "nullable": true, "metadata": { - "description": "Optional. ARM resource ID of the underlying compute." + "description": "Optional. The shared user list of the connection." } }, - "computeType": { + "target": { "type": "string", - "allowedValues": [ - "AKS", - "AmlCompute", - "ComputeInstance", - "Databricks", - "DataFactory", - "DataLakeAnalytics", - "HDInsight", - "Kubernetes", - "SynapseSpark", - "VirtualMachine" - ], "metadata": { - "description": "Required. Set the object type." + "description": "Required. The target of the connection." } }, - "properties": { - "type": "object", + "value": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The properties of the compute. Will be ignored in case \"resourceId\" is set." + "description": "Optional. Value details of the workspace connection." } }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "connectionProperties": { + "$ref": "#/definitions/connectionPropertyType", "metadata": { - "description": "Optional. The managed identity definition for this resource." + "description": "Required. The properties of the connection, specific to the auth type." } } }, - "variables": { - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", - "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" - }, "resources": { "machineLearningWorkspace": { "existing": true, @@ -1390,63 +2926,43 @@ "apiVersion": "2022-10-01", "name": "[parameters('machineLearningWorkspaceName')]" }, - "compute": { - "condition": "[equals(parameters('deployCompute'), true())]", - "type": "Microsoft.MachineLearningServices/workspaces/computes", - "apiVersion": "2022-10-01", + "connection": { + "type": "Microsoft.MachineLearningServices/workspaces/connections", + "apiVersion": "2024-04-01", "name": "[format('{0}/{1}', parameters('machineLearningWorkspaceName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[if(empty(parameters('resourceId')), parameters('tags'), null())]", - "sku": "[if(empty(parameters('resourceId')), createObject('name', parameters('sku'), 'tier', parameters('sku')), null())]", - "identity": "[if(empty(parameters('resourceId')), variables('identity'), null())]", - "properties": "[union(createObject('description', parameters('description'), 'disableLocalAuth', parameters('disableLocalAuth'), 'computeType', parameters('computeType')), if(not(empty(parameters('resourceId'))), createObject('resourceId', parameters('resourceId')), createObject('computeLocation', parameters('computeLocation'), 'properties', parameters('properties'))))]", + "properties": "[union(createObject('category', parameters('category'), 'expiryTime', parameters('expiryTime'), 'isSharedToAll', parameters('isSharedToAll'), 'metadata', parameters('metadata'), 'sharedUserList', parameters('sharedUserList'), 'target', parameters('target'), 'value', parameters('value')), parameters('connectionProperties'))]", "dependsOn": [ "machineLearningWorkspace" ] } }, "outputs": { - "name": { + "resourceId": { "type": "string", "metadata": { - "description": "The name of the compute." + "description": "The resource ID of the connection." }, - "value": "[parameters('name')]" + "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/connections', parameters('machineLearningWorkspaceName'), parameters('name'))]" }, - "resourceId": { + "name": { "type": "string", "metadata": { - "description": "The resource ID of the compute." + "description": "The name of the connection." }, - "value": "[resourceId('Microsoft.MachineLearningServices/workspaces/computes', parameters('machineLearningWorkspaceName'), parameters('name'))]" + "value": "[parameters('name')]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group the compute was deployed into." + "description": "The name of the resource group the connection was created in." }, "value": "[resourceGroup().name]" - }, - "systemAssignedMIPrincipalId": { - "type": "string", - "metadata": { - "description": "The principal ID of the system assigned identity." - }, - "value": "[coalesce(tryGet(tryGet(reference('compute', '2022-10-01', 'full'), 'identity'), 'principalId'), '')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('compute', '2022-10-01', 'full').location]" } } } }, "dependsOn": [ - "workspace", - "workspace_privateEndpoints" + "workspace" ] }, "workspace_privateEndpoints": { diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/ai/dependencies.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/ai/dependencies.bicep index 8ea028e953..9a87497d4f 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/ai/dependencies.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/ai/dependencies.bicep @@ -13,6 +13,9 @@ param storageAccountName string @description('Required. The name of the additional Storage Account to create.') param secondaryStorageAccountName string +@description('Required. The name of the AI Services to create.') +param aiServicesName string + resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { name: keyVaultName location: location @@ -56,6 +59,15 @@ resource secondaryStorageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' kind: 'StorageV2' } +resource aiServices 'Microsoft.CognitiveServices/accounts@2023-05-01' = { + name: aiServicesName + location: location + sku: { + name: 'S0' + } + kind: 'AIServices' +} + @description('The resource ID of the created Application Insights instance.') output applicationInsightsResourceId string = applicationInsights.id @@ -67,3 +79,12 @@ output secondaryStorageAccountResourceId string = secondaryStorageAccount.id @description('The resource ID of the created Key Vault.') output keyVaultResourceId string = keyVault.id + +@description('The resource ID of the created AI Services.') +output aiServicesResourceId string = aiServices.id + +@description('The main endpoint of the created AI Services.') +output aiServicesEndpoint string = aiServices.properties.endpoint + +@description('The endpoints of the created AI Services.') +output aiServicesEndpoints object = aiServices.properties.endpoints diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/ai/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/ai/main.test.bicep index dea496d17f..8ea4b81b79 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/ai/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/ai/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { applicationInsightsName: 'dep-${namePrefix}-appI-${serviceShort}' storageAccountName: 'dep${namePrefix}st${serviceShort}' secondaryStorageAccountName: 'dep${namePrefix}st${serviceShort}2' + aiServicesName: 'dep-${namePrefix}-ai-${serviceShort}' location: resourceLocation } } @@ -63,6 +64,26 @@ module testDeployment '../../../main.bicep' = [ associatedStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId sku: 'Basic' kind: 'Hub' + connections: [ + { + name: 'ai' + category: 'AIServices' + target: nestedDependencies.outputs.aiServicesEndpoint + connectionProperties: { + authType: 'ApiKey' + credentials: { + key: 'key' + } + } + metadata: { + ApiType: 'Azure' + ResourceId: nestedDependencies.outputs.aiServicesResourceId + Location: resourceLocation + ApiVersion: '2023-07-01-preview' + DeploymentApiVersion: '2023-10-01-preview' + } + } + ] workspaceHubConfig: { additionalWorkspaceStorageAccounts: [nestedDependencies.outputs.secondaryStorageAccountResourceId] defaultWorkspaceResourceGroup: resourceGroup.id diff --git a/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep b/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep index 65e1654ec1..56119cb3d1 100644 --- a/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/machine-learning-services/workspace/tests/e2e/max/main.test.bicep @@ -108,6 +108,19 @@ module testDeployment '../../../main.bicep' = [ } } ] + connections: [ + { + name: 'connection' + category: 'ApiKey' + target: 'https://example.com' + connectionProperties: { + authType: 'ApiKey' + credentials: { + key: 'key' + } + } + } + ] description: 'The cake is a lie.' diagnosticSettings: [ { diff --git a/avm/res/machine-learning-services/workspace/version.json b/avm/res/machine-learning-services/workspace/version.json index e42c3d9e5f..a89e5c9d3c 100644 --- a/avm/res/machine-learning-services/workspace/version.json +++ b/avm/res/machine-learning-services/workspace/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.6", - "pathFilters": [ - "./main.json" - ] -} \ No newline at end of file + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.7", + "pathFilters": [ + "./main.json" + ] +}