From 4b3d3d8dd563953197d9d7597614213a5ded3cdb Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 12:11:49 +0100 Subject: [PATCH 01/22] synapse wks draft --- avm/res/synapse/workspace/README.md | 1457 +++++++++++++ .../workspace/integration-runtime/README.md | 81 + .../workspace/integration-runtime/main.bicep | 47 + .../workspace/integration-runtime/main.json | 76 + avm/res/synapse/workspace/key/README.md | 96 + avm/res/synapse/workspace/key/main.bicep | 64 + avm/res/synapse/workspace/key/main.json | 102 + avm/res/synapse/workspace/key/version.json | 7 + avm/res/synapse/workspace/main.bicep | 483 +++++ avm/res/synapse/workspace/main.json | 1794 +++++++++++++++++ .../workspace/modules/nested_cmkRbac.bicep | 40 + .../tests/e2e/defaults/dependencies.bicep | 31 + .../tests/e2e/defaults/main.test.bicep | 58 + .../tests/e2e/encrwsai/dependencies.bicep | 66 + .../tests/e2e/encrwsai/main.test.bicep | 69 + .../tests/e2e/encrwuai/dependencies.bicep | 87 + .../tests/e2e/encrwuai/main.test.bicep | 75 + .../tests/e2e/managedvnet/dependencies.bicep | 31 + .../tests/e2e/managedvnet/main.test.bicep | 70 + .../tests/e2e/max/dependencies.bicep | 92 + .../workspace/tests/e2e/max/main.test.bicep | 135 ++ .../tests/e2e/waf-aligned/dependencies.bicep | 92 + .../tests/e2e/waf-aligned/main.test.bicep | 118 ++ avm/res/synapse/workspace/version.json | 7 + 24 files changed, 5178 insertions(+) create mode 100644 avm/res/synapse/workspace/README.md create mode 100644 avm/res/synapse/workspace/integration-runtime/README.md create mode 100644 avm/res/synapse/workspace/integration-runtime/main.bicep create mode 100644 avm/res/synapse/workspace/integration-runtime/main.json create mode 100644 avm/res/synapse/workspace/key/README.md create mode 100644 avm/res/synapse/workspace/key/main.bicep create mode 100644 avm/res/synapse/workspace/key/main.json create mode 100644 avm/res/synapse/workspace/key/version.json create mode 100644 avm/res/synapse/workspace/main.bicep create mode 100644 avm/res/synapse/workspace/main.json create mode 100644 avm/res/synapse/workspace/modules/nested_cmkRbac.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/max/main.test.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep create mode 100644 avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep create mode 100644 avm/res/synapse/workspace/version.json diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md new file mode 100644 index 0000000000..74e737772b --- /dev/null +++ b/avm/res/synapse/workspace/README.md @@ -0,0 +1,1457 @@ +# Synapse Workspaces `[Microsoft.Synapse/workspaces]` + +This module deploys a Synapse Workspace. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.KeyVault/vaults/accessPolicies` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/accessPolicies) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | +| `Microsoft.Synapse/workspaces` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces) | +| `Microsoft.Synapse/workspaces/integrationRuntimes` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/integrationRuntimes) | +| `Microsoft.Synapse/workspaces/keys` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/keys) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/synapse/workspace:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using Customer-Managed-Keys with System-Assigned identity](#example-2-using-customer-managed-keys-with-system-assigned-identity) +- [Using Customer-Managed-Keys with User-Assigned identity](#example-3-using-customer-managed-keys-with-user-assigned-identity) +- [Using Managed Workspace Vnet](#example-4-using-managed-workspace-vnet) +- [Using large parameter set](#example-5-using-large-parameter-set) +- [WAF-aligned](#example-6-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swmin' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmin001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmin001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 2: _Using Customer-Managed-Keys with System-Assigned identity_ + +This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret. + + +

+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swensa' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swensa001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + customerManagedKey: { + keyName: '' + keyVaultResourceId: '' + } + encryptionActivateWorkspace: true + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swensa001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "keyName": "", + "keyVaultResourceId": "" + } + }, + "encryptionActivateWorkspace": { + "value": true + }, + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 3: _Using Customer-Managed-Keys with User-Assigned identity_ + +This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. + + +

+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swenua' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swenua001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + customerManagedKey: { + keyName: '' + keyVaultResourceId: '' + userAssignedIdentityResourceId: '' + } + location: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swenua001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "keyName": "", + "keyVaultResourceId": "", + "userAssignedIdentityResourceId": "" + } + }, + "location": { + "value": "" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 4: _Using Managed Workspace Vnet_ + +This instance deploys the module associating the workspace to a Managed workspace Virtual Netowork. + + +

+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swmanv' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmanv001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + allowedAadTenantIdsForLinking: [ + '' + ] + location: '' + managedVirtualNetwork: true + preventDataExfiltration: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmanv001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "allowedAadTenantIdsForLinking": { + "value": [ + "" + ] + }, + "location": { + "value": "" + }, + "managedVirtualNetwork": { + "value": true + }, + "preventDataExfiltration": { + "value": true + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 5: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swmax' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swmax001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + initialWorkspaceAdminObjectID: '' + integrationRuntimes: [ + { + name: 'shir01' + type: 'SelfHosted' + } + ] + location: '' + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + managedVirtualNetwork: true + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'SQL' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swmax001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "category": "SynapseRbacOperations" + }, + { + "category": "SynapseLinkEvent" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "initialWorkspaceAdminObjectID": { + "value": "" + }, + "integrationRuntimes": { + "value": [ + { + "name": "shir01", + "type": "SelfHosted" + } + ] + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "managedVirtualNetwork": { + "value": true + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "SQL", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + } + } +} +``` + +
+

+ +### Example 6: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

+ +via Bicep module + +```bicep +module workspace 'br/public:avm/res/synapse/workspace:' = { + name: '${uniqueString(deployment().name, location)}-test-swwaf' + params: { + // Required parameters + defaultDataLakeStorageAccountResourceId: '' + defaultDataLakeStorageFilesystem: '' + name: 'swwaf001' + sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + initialWorkspaceAdminObjectID: '' + integrationRuntimes: [ + { + name: 'shir01' + type: 'SelfHosted' + } + ] + location: '' + managedIdentities: { + userAssignedResourceIds: [ + '' + ] + } + managedVirtualNetwork: true + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'SQL' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "defaultDataLakeStorageAccountResourceId": { + "value": "" + }, + "defaultDataLakeStorageFilesystem": { + "value": "" + }, + "name": { + "value": "swwaf001" + }, + "sqlAdministratorLogin": { + "value": "synwsadmin" + }, + // Non-required parameters + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "logCategoriesAndGroups": [ + { + "category": "SynapseRbacOperations" + }, + { + "category": "SynapseLinkEvent" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "initialWorkspaceAdminObjectID": { + "value": "" + }, + "integrationRuntimes": { + "value": [ + { + "name": "shir01", + "type": "SelfHosted" + } + ] + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "userAssignedResourceIds": [ + "" + ] + } + }, + "managedVirtualNetwork": { + "value": true + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "SQL", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`defaultDataLakeStorageAccountResourceId`](#parameter-defaultdatalakestorageaccountresourceid) | string | Resource ID of the default ADLS Gen2 storage account. | +| [`defaultDataLakeStorageFilesystem`](#parameter-defaultdatalakestoragefilesystem) | string | The default ADLS Gen2 file system. | +| [`name`](#parameter-name) | string | The name of the Synapse Workspace. | +| [`sqlAdministratorLogin`](#parameter-sqladministratorlogin) | string | Login for administrator access to the workspace's SQL pools. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`allowedAadTenantIdsForLinking`](#parameter-allowedaadtenantidsforlinking) | array | Allowed AAD Tenant IDs For Linking. | +| [`azureADOnlyAuthentication`](#parameter-azureadonlyauthentication) | bool | Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource. | +| [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | +| [`defaultDataLakeStorageCreateManagedPrivateEndpoint`](#parameter-defaultdatalakestoragecreatemanagedprivateendpoint) | bool | Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`encryptionActivateWorkspace`](#parameter-encryptionactivateworkspace) | bool | Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace. | +| [`initialWorkspaceAdminObjectID`](#parameter-initialworkspaceadminobjectid) | string | AAD object ID of initial workspace admin. | +| [`integrationRuntimes`](#parameter-integrationruntimes) | array | The Integration Runtimes to create. | +| [`linkedAccessCheckOnTargetResource`](#parameter-linkedaccesscheckontargetresource) | bool | Linked Access Check On Target Resource. | +| [`location`](#parameter-location) | string | The geo-location where the resource lives. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | +| [`managedResourceGroupName`](#parameter-managedresourcegroupname) | string | Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'. | +| [`managedVirtualNetwork`](#parameter-managedvirtualnetwork) | bool | Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources. | +| [`preventDataExfiltration`](#parameter-preventdataexfiltration) | bool | Prevent Data Exfiltration. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Enable or Disable public network access to workspace. | +| [`purviewResourceID`](#parameter-purviewresourceid) | string | Purview Resource ID. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`sqlAdministratorLoginPassword`](#parameter-sqladministratorloginpassword) | string | Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`workspaceRepositoryConfiguration`](#parameter-workspacerepositoryconfiguration) | object | Git integration settings. | + +### Parameter: `defaultDataLakeStorageAccountResourceId` + +Resource ID of the default ADLS Gen2 storage account. + +- Required: Yes +- Type: string + +### Parameter: `defaultDataLakeStorageFilesystem` + +The default ADLS Gen2 file system. + +- Required: Yes +- Type: string + +### Parameter: `name` + +The name of the Synapse Workspace. + +- Required: Yes +- Type: string + +### Parameter: `sqlAdministratorLogin` + +Login for administrator access to the workspace's SQL pools. + +- Required: Yes +- Type: string + +### Parameter: `allowedAadTenantIdsForLinking` + +Allowed AAD Tenant IDs For Linking. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `azureADOnlyAuthentication` + +Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `customerManagedKey` + +The customer managed key definition. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | +| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, using 'latest'. | +| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | + +### Parameter: `customerManagedKey.keyName` + +The name of the customer managed key to use for encryption. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVersion` + +The version of the customer managed key to reference for encryption. If not provided, using 'latest'. + +- Required: No +- Type: string + +### Parameter: `customerManagedKey.userAssignedIdentityResourceId` + +User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. + +- Required: No +- Type: string + +### Parameter: `defaultDataLakeStorageCreateManagedPrivateEndpoint` + +Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to '' to disable log collection. + +- Required: No +- Type: array + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `encryptionActivateWorkspace` + +Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `initialWorkspaceAdminObjectID` + +AAD object ID of initial workspace admin. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `integrationRuntimes` + +The Integration Runtimes to create. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `linkedAccessCheckOnTargetResource` + +Linked Access Check On Target Resource. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `location` + +The geo-location where the resource lives. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: Yes +- Type: array + +### Parameter: `managedResourceGroupName` + +Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `managedVirtualNetwork` + +Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `preventDataExfiltration` + +Prevent Data Exfiltration. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualPrivateLinkServiceConnections`](#parameter-privateendpointsmanualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.service` + +The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualPrivateLinkServiceConnections` + +Manual PrivateLink Service Connections. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `publicNetworkAccess` + +Enable or Disable public network access to workspace. + +- Required: No +- Type: string +- Default: `'Enabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `purviewResourceID` + +Purview Resource ID. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `sqlAdministratorLoginPassword` + +Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `workspaceRepositoryConfiguration` + +Git integration settings. + +- Required: No +- Type: object +- Default: `{}` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `connectivityEndpoints` | object | The workspace connectivity endpoints. | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the deployed Synapse Workspace. | +| `resourceGroupName` | string | The resource group of the deployed Synapse Workspace. | +| `resourceID` | string | The resource ID of the deployed Synapse Workspace. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | diff --git a/avm/res/synapse/workspace/integration-runtime/README.md b/avm/res/synapse/workspace/integration-runtime/README.md new file mode 100644 index 0000000000..2f19cdc324 --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/README.md @@ -0,0 +1,81 @@ +# Synapse Workspace Integration Runtimes `[Microsoft.Synapse/workspaces/integrationRuntimes]` + +This module deploys a Synapse Workspace Integration Runtime. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Synapse/workspaces/integrationRuntimes` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/integrationRuntimes) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the Integration Runtime. | +| [`type`](#parameter-type) | string | The type of Integration Runtime. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`typeProperties`](#parameter-typeproperties) | object | Integration Runtime type properties. Required if type is "Managed". | +| [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. | + +### Parameter: `name` + +The name of the Integration Runtime. + +- Required: Yes +- Type: string + +### Parameter: `type` + +The type of Integration Runtime. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Managed' + 'SelfHosted' + ] + ``` + +### Parameter: `typeProperties` + +Integration Runtime type properties. Required if type is "Managed". + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `workspaceName` + +The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the Integration Runtime. | +| `resourceGroupName` | string | The name of the Resource Group the Integration Runtime was created in. | +| `resourceId` | string | The resource ID of the Integration Runtime. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/synapse/workspace/integration-runtime/main.bicep b/avm/res/synapse/workspace/integration-runtime/main.bicep new file mode 100644 index 0000000000..2734626027 --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/main.bicep @@ -0,0 +1,47 @@ +metadata name = 'Synapse Workspace Integration Runtimes' +metadata description = 'This module deploys a Synapse Workspace Integration Runtime.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +param workspaceName string + +@description('Required. The name of the Integration Runtime.') +param name string + +@allowed([ + 'Managed' + 'SelfHosted' +]) +@description('Required. The type of Integration Runtime.') +param type string + +@description('Conditional. Integration Runtime type properties. Required if type is "Managed".') +param typeProperties object = {} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { + name: workspaceName +} + +resource integrationRuntime 'Microsoft.Synapse/workspaces/integrationRuntimes@2021-06-01' = { + name: name + parent: workspace + properties: type == 'Managed' ? { + type: type + managedVirtualNetwork: { + referenceName: 'default' + type: 'ManagedVirtualNetworkReference' + } + typeProperties: typeProperties + } : { + type: type + } +} + +@description('The name of the Resource Group the Integration Runtime was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The name of the Integration Runtime.') +output name string = integrationRuntime.name + +@description('The resource ID of the Integration Runtime.') +output resourceId string = integrationRuntime.id diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json new file mode 100644 index 0000000000..94a7fe2f1b --- /dev/null +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -0,0 +1,76 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "2245322500910751784" + }, + "name": "Synapse Workspace Integration Runtimes", + "description": "This module deploys a Synapse Workspace Integration Runtime.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Integration Runtime." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "Managed", + "SelfHosted" + ], + "metadata": { + "description": "Required. The type of Integration Runtime." + } + }, + "typeProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/integrationRuntimes", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": "[if(equals(parameters('type'), 'Managed'), createObject('type', parameters('type'), 'managedVirtualNetwork', createObject('referenceName', 'default', 'type', 'ManagedVirtualNetworkReference'), 'typeProperties', parameters('typeProperties')), createObject('type', parameters('type')))]" + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Integration Runtime was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Integration Runtime." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Integration Runtime." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/integrationRuntimes', parameters('workspaceName'), parameters('name'))]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/key/README.md b/avm/res/synapse/workspace/key/README.md new file mode 100644 index 0000000000..667aefb54b --- /dev/null +++ b/avm/res/synapse/workspace/key/README.md @@ -0,0 +1,96 @@ +# Synapse Workspaces Keys `[Microsoft.Synapse/workspaces/keys]` + +This module deploys a Synapse Workspaces Key. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Synapse/workspaces/keys` | [2021-06-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/workspaces/keys) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`isActiveCMK`](#parameter-isactivecmk) | bool | Used to activate the workspace after a customer managed key is provided. | +| [`keyVaultResourceId`](#parameter-keyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | +| [`name`](#parameter-name) | string | Encryption key name. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`location`](#parameter-location) | string | The geo-location where the resource lives. | + +### Parameter: `isActiveCMK` + +Used to activate the workspace after a customer managed key is provided. + +- Required: Yes +- Type: bool + +### Parameter: `keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `name` + +Encryption key name. + +- Required: Yes +- Type: string + +### Parameter: `workspaceName` + +The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +The geo-location where the resource lives. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the deployed key. | +| `resourceGroupName` | string | The resource group of the deployed key. | +| `resourceId` | string | The resource ID of the deployed key. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/synapse/workspace/key/main.bicep b/avm/res/synapse/workspace/key/main.bicep new file mode 100644 index 0000000000..7ae64222fc --- /dev/null +++ b/avm/res/synapse/workspace/key/main.bicep @@ -0,0 +1,64 @@ +metadata name = 'Synapse Workspaces Keys' +metadata description = 'This module deploys a Synapse Workspaces Key.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Encryption key name.') +param name string + +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +param workspaceName string + +@description('Optional. The geo-location where the resource lives.') +param location string = resourceGroup().location + +@description('Required. Used to activate the workspace after a customer managed key is provided.') +param isActiveCMK bool + +@description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') +param keyVaultResourceId string + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = { + name: last(split(keyVaultResourceId, '/')) + scope: resourceGroup(split(keyVaultResourceId, '/')[2], split(keyVaultResourceId, '/')[4]) + + resource cMKKey 'keys@2023-02-01' existing = { + name: name + } +} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { + name: workspaceName +} + +resource key 'Microsoft.Synapse/workspaces/keys@2021-06-01' = { + name: name + parent: workspace + properties: { + isActiveCMK: isActiveCMK + keyVaultUrl: cMKKeyVault::cMKKey.properties.keyUri + } +} + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +@description('The name of the deployed key.') +output name string = key.name + +@description('The resource ID of the deployed key.') +output resourceId string = key.id + +@description('The resource group of the deployed key.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json new file mode 100644 index 0000000000..371874873e --- /dev/null +++ b/avm/res/synapse/workspace/key/main.json @@ -0,0 +1,102 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "17878422697036938783" + }, + "name": "Synapse Workspaces Keys", + "description": "This module deploys a Synapse Workspaces Key.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Encryption key name." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The geo-location where the resource lives." + } + }, + "isActiveCMK": { + "type": "bool", + "metadata": { + "description": "Required. Used to activate the workspace after a customer managed key is provided." + } + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/keys", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "isActiveCMK": "[parameters('isActiveCMK')]", + "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" + } + }, + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed key." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/keys', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed key." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/key/version.json b/avm/res/synapse/workspace/key/version.json new file mode 100644 index 0000000000..96236a61ba --- /dev/null +++ b/avm/res/synapse/workspace/key/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.4", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep new file mode 100644 index 0000000000..1a39ac0a28 --- /dev/null +++ b/avm/res/synapse/workspace/main.bicep @@ -0,0 +1,483 @@ +metadata name = 'Synapse Workspaces' +metadata description = 'This module deploys a Synapse Workspace.' +metadata owner = 'Azure/module-maintainers' + +// Parameters +@maxLength(50) +@description('Required. The name of the Synapse Workspace.') +param name string + +@description('Optional. The geo-location where the resource lives.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource.') +param azureADOnlyAuthentication bool = false + +@description('Optional. AAD object ID of initial workspace admin.') +param initialWorkspaceAdminObjectID string = '' + +@description('Required. Resource ID of the default ADLS Gen2 storage account.') +param defaultDataLakeStorageAccountResourceId string + +@description('Required. The default ADLS Gen2 file system.') +param defaultDataLakeStorageFilesystem string + +@description('Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace\'s primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account.') +param defaultDataLakeStorageCreateManagedPrivateEndpoint bool = false + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. The customer managed key definition.') +param customerManagedKey customerManagedKeyType + +@description('Optional. Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace.') +param encryptionActivateWorkspace bool = false + +@maxLength(90) +@description('Optional. Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and \'-\', \'_\', \'(\', \')\' and\'.\'. Note that the name cannot end with \'.\'.') +param managedResourceGroupName string = '' + +@description('Optional. Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources.') +param managedVirtualNetwork bool = false + +@description('Optional. The Integration Runtimes to create.') +param integrationRuntimes array = [] + +@description('Optional. Allowed AAD Tenant IDs For Linking.') +param allowedAadTenantIdsForLinking array = [] + +@description('Optional. Linked Access Check On Target Resource.') +param linkedAccessCheckOnTargetResource bool = false + +@description('Optional. Prevent Data Exfiltration.') +param preventDataExfiltration bool = false + +@allowed([ + 'Enabled' + 'Disabled' +]) +@description('Optional. Enable or Disable public network access to workspace.') +param publicNetworkAccess string = 'Enabled' + +@description('Optional. Purview Resource ID.') +param purviewResourceID string = '' + +@description('Required. Login for administrator access to the workspace\'s SQL pools.') +param sqlAdministratorLogin string + +@description('Optional. Password for administrator access to the workspace\'s SQL pools. If you don\'t provide a password, one will be automatically generated. You can change the password later.') +#disable-next-line secure-secrets-in-params // Not a secret +param sqlAdministratorLoginPassword string = '' + +@description('Optional. Git integration settings.') +param workspaceRepositoryConfiguration object = {} + +@description('Optional. The managed identity definition for this resource.') +param managedIdentities managedIdentitiesType + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints privateEndpointType + +@description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + +// Variables + +var cmkUserAssignedIdentityAsArray = !empty(customerManagedKey.?userAssignedIdentityResourceId ?? []) ? [ customerManagedKey.?userAssignedIdentityResourceId ] : [] + +var userAssignedIdentitiesUnion = !empty(managedIdentities) ? union(managedIdentities.?userAssignedResourceIds ?? [], cmkUserAssignedIdentityAsArray) : cmkUserAssignedIdentityAsArray + +var formattedUserAssignedIdentities = reduce(map((userAssignedIdentitiesUnion ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = { + type: !empty(userAssignedIdentitiesUnion) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned' + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null +} + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.synapse-workspace.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId)) { + name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup(split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4]) + + resource cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { + name: customerManagedKey.?keyName ?? 'dummyKey' + } +} + +resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup(split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4]) +} + +resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' = { + name: name + location: location + identity: identity + tags: tags + properties: { + azureADOnlyAuthentication: azureADOnlyAuthentication ? azureADOnlyAuthentication : null + cspWorkspaceAdminProperties: !empty(initialWorkspaceAdminObjectID) ? { + initialWorkspaceAdminObjectId: initialWorkspaceAdminObjectID + } : null + defaultDataLakeStorage: { + resourceId: defaultDataLakeStorageAccountResourceId + accountUrl: 'https://${last(split(defaultDataLakeStorageAccountResourceId, '/'))!}.dfs.${environment().suffixes.storage}' + filesystem: defaultDataLakeStorageFilesystem + createManagedPrivateEndpoint: managedVirtualNetwork ? defaultDataLakeStorageCreateManagedPrivateEndpoint : null + } + encryption: !empty(customerManagedKey) ? { + cmk: { + kekIdentity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } : { + useSystemAssignedIdentity: empty(customerManagedKey.?userAssignedIdentityResourceId) + } + + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } : null + + key: { + keyVaultUrl: cMKKeyVault::cMKKey.properties.keyUri + name: customerManagedKey!.keyName + } + } + } : null + managedResourceGroupName: !empty(managedResourceGroupName) ? managedResourceGroupName : null + managedVirtualNetwork: managedVirtualNetwork ? 'default' : null + managedVirtualNetworkSettings: managedVirtualNetwork ? { + allowedAadTenantIdsForLinking: allowedAadTenantIdsForLinking + linkedAccessCheckOnTargetResource: linkedAccessCheckOnTargetResource + preventDataExfiltration: preventDataExfiltration + } : null + publicNetworkAccess: managedVirtualNetwork ? publicNetworkAccess : null + purviewConfiguration: !empty(purviewResourceID) ? { + purviewResourceId: purviewResourceID + } : null + sqlAdministratorLogin: sqlAdministratorLogin + sqlAdministratorLoginPassword: !empty(sqlAdministratorLoginPassword) ? sqlAdministratorLoginPassword : null + workspaceRepositoryConfiguration: workspaceRepositoryConfiguration + } +} + +// Workspace integration runtimes +module synapse_integrationRuntimes 'integration-runtime/main.bicep' = [for (integrationRuntime, index) in integrationRuntimes: { + name: '${uniqueString(deployment().name, location)}-Synapse-IntegrationRuntime-${index}' + params: { + workspaceName: workspace.name + name: integrationRuntime.name + type: integrationRuntime.type + typeProperties: contains(integrationRuntime, 'typeProperties') ? integrationRuntime.typeProperties : {} + } +}] + +// Workspace encryption with customer managed keys +// - Assign Synapse Workspace MSI access to encryption key +module workspace_cmk_rbac 'modules/nested_cmkRbac.bicep' = if (encryptionActivateWorkspace) { + name: '${workspace.name}-cmk-rbac' + params: { + workspaceIndentityPrincipalId: workspace.identity.principalId + keyvaultName: !empty(customerManagedKey.?keyVaultResourceId) ? cMKKeyVault.name : '' + usesRbacAuthorization: !empty(customerManagedKey.?keyVaultResourceId) ? cMKKeyVault.properties.enableRbacAuthorization : true + } + scope: encryptionActivateWorkspace ? resourceGroup(split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4]) : resourceGroup() +} + +// - Workspace encryption - Activate Workspace +module workspace_key 'key/main.bicep' = if (encryptionActivateWorkspace) { + name: '${workspace.name}-cmk-activation' + params: { + name: customerManagedKey!.keyName + location: location + isActiveCMK: true + keyVaultResourceId: cMKKeyVault.id + workspaceName: workspace.name + } + dependsOn: [ + workspace_cmk_rbac + ] +} + +// Resource Lock +resource workspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: workspace +} + +// RBAC +resource workspace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(workspace.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: workspace +}] + +// Endpoints +module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.3.1' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-workspace-PrivateEndpoint-${index}' + params: { + privateLinkServiceConnections: [ + { + name: name + properties: { + privateLinkServiceId: workspace.id + groupIds: [ + privateEndpoint.?service ?? 'vault' + ] + } + } + ] + name: privateEndpoint.?name ?? 'pep-${last(split(workspace.id, '/'))}-${privateEndpoint.?service ?? privateEndpoint.service}-${index}' + subnetResourceId: privateEndpoint.subnetResourceId + location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } +}] + +// Diagnostics Settings +resource workspace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + logs: diagnosticSetting.?logCategoriesAndGroups ?? [ + { + categoryGroup: 'AllLogs' + enabled: true + } + ] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: workspace +}] + +@description('The resource ID of the deployed Synapse Workspace.') +output resourceID string = workspace.id + +@description('The name of the deployed Synapse Workspace.') +output name string = workspace.name + +@description('The resource group of the deployed Synapse Workspace.') +output resourceGroupName string = resourceGroup().name + +@description('The workspace connectivity endpoints.') +output connectivityEndpoints object = workspace.properties.connectivityEndpoints + +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = contains(workspace.identity, 'principalId') ? workspace.identity.principalId : '' + +@description('The location the resource was deployed into.') +output location string = workspace.location + +// =============== // +// Definitions // +// =============== // + +type managedIdentitiesType = { + @description('Optional. The resource ID(s) to assign to the resource.') + userAssignedResourceIds: string[] +}? + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + @description('Optional. The name of the private endpoint.') + name: string? + + @description('Optional. The location to deploy the private endpoint to.') + location: string? + + @description('Required. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".') + service: string + + @description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @description('Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided.') + privateDnsZoneGroupName: string? + + @description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @description('Required. Fqdn that resolves to private endpoint ip address.') + fqdn: string? + + @description('Required. A list of private ip addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @description('Required. The name of the resource that is unique within a resource group.') + name: string + + @description('Required. Properties of private endpoint IP configurations.') + properties: { + @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @description('Required. A private ip address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @description('Optional. Specify the type of lock.') + lock: lockType + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @description('Optional. Manual PrivateLink Service Connections.') + manualPrivateLinkServiceConnections: array? + + @description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \'AllLogs\' to collect all logs.') + categoryGroup: string? + }[]? + + @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type customerManagedKeyType = { + @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') + keyVaultResourceId: string + + @description('Required. The name of the customer managed key to use for encryption.') + keyName: string + + @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using \'latest\'.') + keyVersion: string? + + @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? +}? diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json new file mode 100644 index 0000000000..b294f7dc1b --- /dev/null +++ b/avm/res/synapse/workspace/main.json @@ -0,0 +1,1794 @@ +{ + "$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.23.1.45101", + "templateHash": "17529076065679517867" + }, + "name": "Synapse Workspaces", + "description": "This module deploys a Synapse Workspace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "metadata": { + "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to 'AllLogs' to collect all logs." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to '' to disable log collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 50, + "metadata": { + "description": "Required. The name of the Synapse Workspace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The geo-location where the resource lives." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "azureADOnlyAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource." + } + }, + "initialWorkspaceAdminObjectID": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. AAD object ID of initial workspace admin." + } + }, + "defaultDataLakeStorageAccountResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the default ADLS Gen2 storage account." + } + }, + "defaultDataLakeStorageFilesystem": { + "type": "string", + "metadata": { + "description": "Required. The default ADLS Gen2 file system." + } + }, + "defaultDataLakeStorageCreateManagedPrivateEndpoint": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "encryptionActivateWorkspace": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Activate workspace by adding the system managed identity in the KeyVault containing the customer managed key and activating the workspace." + } + }, + "managedResourceGroupName": { + "type": "string", + "defaultValue": "", + "maxLength": 90, + "metadata": { + "description": "Optional. Workspace managed resource group. The resource group name uniquely identifies the resource group within the user subscriptionId. The resource group name must be no longer than 90 characters long, and must be alphanumeric characters (Char.IsLetterOrDigit()) and '-', '_', '(', ')' and'.'. Note that the name cannot end with '.'." + } + }, + "managedVirtualNetwork": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable this to ensure that connection from your workspace to your data sources use Azure Private Links. You can create managed private endpoints to your data sources." + } + }, + "integrationRuntimes": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The Integration Runtimes to create." + } + }, + "allowedAadTenantIdsForLinking": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Allowed AAD Tenant IDs For Linking." + } + }, + "linkedAccessCheckOnTargetResource": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Linked Access Check On Target Resource." + } + }, + "preventDataExfiltration": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Prevent Data Exfiltration." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Enable or Disable public network access to workspace." + } + }, + "purviewResourceID": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Purview Resource ID." + } + }, + "sqlAdministratorLogin": { + "type": "string", + "metadata": { + "description": "Required. Login for administrator access to the workspace's SQL pools." + } + }, + "sqlAdministratorLoginPassword": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Password for administrator access to the workspace's SQL pools. If you don't provide a password, one will be automatically generated. You can change the password later." + } + }, + "workspaceRepositoryConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Git integration settings." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "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." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "cmkUserAssignedIdentityAsArray": "[if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), createArray()))), createArray(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')), createArray())]", + "userAssignedIdentitiesUnion": "[if(not(empty(parameters('managedIdentities'))), union(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), variables('cmkUserAssignedIdentityAsArray')), variables('cmkUserAssignedIdentityAsArray'))]", + "formattedUserAssignedIdentities": "[reduce(map(coalesce(variables('userAssignedIdentitiesUnion'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": { + "type": "[if(not(empty(variables('userAssignedIdentitiesUnion'))), 'SystemAssigned,UserAssigned', 'SystemAssigned')]", + "userAssignedIdentities": "[if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())]" + }, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.synapse-workspace.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "workspace": { + "type": "Microsoft.Synapse/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "properties": { + "azureADOnlyAuthentication": "[if(parameters('azureADOnlyAuthentication'), parameters('azureADOnlyAuthentication'), null())]", + "cspWorkspaceAdminProperties": "[if(not(empty(parameters('initialWorkspaceAdminObjectID'))), createObject('initialWorkspaceAdminObjectId', parameters('initialWorkspaceAdminObjectID')), null())]", + "defaultDataLakeStorage": { + "resourceId": "[parameters('defaultDataLakeStorageAccountResourceId')]", + "accountUrl": "[format('https://{0}.dfs.{1}', last(split(parameters('defaultDataLakeStorageAccountResourceId'), '/')), environment().suffixes.storage)]", + "filesystem": "[parameters('defaultDataLakeStorageFilesystem')]", + "createManagedPrivateEndpoint": "[if(parameters('managedVirtualNetwork'), parameters('defaultDataLakeStorageCreateManagedPrivateEndpoint'), null())]" + }, + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('cmk', createObject('kekIdentity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), createObject('useSystemAssignedIdentity', empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))), 'identity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), null()), 'key', createObject('keyVaultUrl', reference('cMKKeyVault::cMKKey').keyUri, 'name', parameters('customerManagedKey').keyName))), null())]", + "managedResourceGroupName": "[if(not(empty(parameters('managedResourceGroupName'))), parameters('managedResourceGroupName'), null())]", + "managedVirtualNetwork": "[if(parameters('managedVirtualNetwork'), 'default', null())]", + "managedVirtualNetworkSettings": "[if(parameters('managedVirtualNetwork'), createObject('allowedAadTenantIdsForLinking', parameters('allowedAadTenantIdsForLinking'), 'linkedAccessCheckOnTargetResource', parameters('linkedAccessCheckOnTargetResource'), 'preventDataExfiltration', parameters('preventDataExfiltration')), null())]", + "publicNetworkAccess": "[if(parameters('managedVirtualNetwork'), parameters('publicNetworkAccess'), null())]", + "purviewConfiguration": "[if(not(empty(parameters('purviewResourceID'))), createObject('purviewResourceId', parameters('purviewResourceID')), null())]", + "sqlAdministratorLogin": "[parameters('sqlAdministratorLogin')]", + "sqlAdministratorLoginPassword": "[if(not(empty(parameters('sqlAdministratorLoginPassword'))), parameters('sqlAdministratorLoginPassword'), null())]", + "workspaceRepositoryConfiguration": "[parameters('workspaceRepositoryConfiguration')]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "workspace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_roleAssignments": { + "copy": { + "name": "workspace_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Synapse/workspaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_diagnosticSettings": { + "copy": { + "name": "workspace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Synapse/workspaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "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')]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "workspace" + ] + }, + "synapse_integrationRuntimes": { + "copy": { + "name": "synapse_integrationRuntimes", + "count": "[length(parameters('integrationRuntimes'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Synapse-IntegrationRuntime-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('integrationRuntimes')[copyIndex()].name]" + }, + "type": { + "value": "[parameters('integrationRuntimes')[copyIndex()].type]" + }, + "typeProperties": "[if(contains(parameters('integrationRuntimes')[copyIndex()], 'typeProperties'), createObject('value', parameters('integrationRuntimes')[copyIndex()].typeProperties), createObject('value', createObject()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "2245322500910751784" + }, + "name": "Synapse Workspace Integration Runtimes", + "description": "This module deploys a Synapse Workspace Integration Runtime.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Integration Runtime." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "Managed", + "SelfHosted" + ], + "metadata": { + "description": "Required. The type of Integration Runtime." + } + }, + "typeProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/integrationRuntimes", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": "[if(equals(parameters('type'), 'Managed'), createObject('type', parameters('type'), 'managedVirtualNetwork', createObject('referenceName', 'default', 'type', 'ManagedVirtualNetworkReference'), 'typeProperties', parameters('typeProperties')), createObject('type', parameters('type')))]" + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the Integration Runtime was created in." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Integration Runtime." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Integration Runtime." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/integrationRuntimes', parameters('workspaceName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + }, + "workspace_cmk_rbac": { + "condition": "[parameters('encryptionActivateWorkspace')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cmk-rbac', parameters('name'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "workspaceIndentityPrincipalId": { + "value": "[reference('workspace', '2021-06-01', 'full').identity.principalId]" + }, + "keyvaultName": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), createObject('value', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))), createObject('value', ''))]", + "usesRbacAuthorization": "[if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), createObject('value', reference('cMKKeyVault').enableRbacAuthorization), createObject('value', true()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "1182711601328740781" + } + }, + "parameters": { + "keyvaultName": { + "type": "string" + }, + "workspaceIndentityPrincipalId": { + "type": "string" + }, + "usesRbacAuthorization": { + "type": "bool", + "defaultValue": false + } + }, + "resources": [ + { + "condition": "[parameters('usesRbacAuthorization')]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyvaultName'))]", + "name": "[guid(format('{0}-{1}-Key-Vault-Crypto-User', resourceId('Microsoft.KeyVault/vaults', parameters('keyvaultName')), parameters('workspaceIndentityPrincipalId')))]", + "properties": { + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')]", + "principalId": "[parameters('workspaceIndentityPrincipalId')]", + "principalType": "ServicePrincipal" + } + }, + { + "condition": "[not(parameters('usesRbacAuthorization'))]", + "type": "Microsoft.KeyVault/vaults/accessPolicies", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyvaultName'), 'add')]", + "properties": { + "accessPolicies": [ + { + "permissions": { + "keys": [ + "wrapKey", + "unwrapKey", + "get" + ] + }, + "objectId": "[parameters('workspaceIndentityPrincipalId')]", + "tenantId": "[tenant().tenantId]" + } + ] + } + } + ] + } + }, + "dependsOn": [ + "cMKKeyVault", + "workspace" + ] + }, + "workspace_key": { + "condition": "[parameters('encryptionActivateWorkspace')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cmk-activation', parameters('name'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('customerManagedKey').keyName]" + }, + "location": { + "value": "[parameters('location')]" + }, + "isActiveCMK": { + "value": true + }, + "keyVaultResourceId": { + "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]), 'Microsoft.KeyVault/vaults', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')))]" + }, + "workspaceName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "17878422697036938783" + }, + "name": "Synapse Workspaces Keys", + "description": "This module deploys a Synapse Workspaces Key.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Encryption key name." + } + }, + "workspaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The geo-location where the resource lives." + } + }, + "isActiveCMK": { + "type": "bool", + "metadata": { + "description": "Required. Used to activate the workspace after a customer managed key is provided." + } + }, + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "type": "Microsoft.Synapse/workspaces/keys", + "apiVersion": "2021-06-01", + "name": "[format('{0}/{1}', parameters('workspaceName'), parameters('name'))]", + "properties": { + "isActiveCMK": "[parameters('isActiveCMK')]", + "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" + } + }, + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed key." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed key." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces/keys', parameters('workspaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed key." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "cMKKeyVault", + "workspace", + "workspace_cmk_rbac" + ] + }, + "workspace_privateEndpoints": { + "copy": { + "name": "workspace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-workspace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateLinkServiceConnections": { + "value": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]", + "groupIds": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')]" + ] + } + } + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Synapse/workspaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), copyIndex()))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "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.23.1.45101", + "templateHash": "2821141217598568122" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private ip address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint ip address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private ip addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18168683629401652671" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "workspace" + ] + } + }, + "outputs": { + "resourceID": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed Synapse Workspace." + }, + "value": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed Synapse Workspace." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed Synapse Workspace." + }, + "value": "[resourceGroup().name]" + }, + "connectivityEndpoints": { + "type": "object", + "metadata": { + "description": "The workspace connectivity endpoints." + }, + "value": "[reference('workspace').connectivityEndpoints]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[if(contains(reference('workspace', '2021-06-01', 'full').identity, 'principalId'), reference('workspace', '2021-06-01', 'full').identity.principalId, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('workspace', '2021-06-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep b/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep new file mode 100644 index 0000000000..1c14980eb9 --- /dev/null +++ b/avm/res/synapse/workspace/modules/nested_cmkRbac.bicep @@ -0,0 +1,40 @@ +param keyvaultName string +param workspaceIndentityPrincipalId string +param usesRbacAuthorization bool = false + +// Workspace encryption - Assign Workspace System Identity Keyvault Crypto Reader at Encryption Keyvault +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = { + name: keyvaultName +} + +// Assign RBAC role Key Vault Crypto User +resource workspace_cmk_rbac 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (usesRbacAuthorization) { + name: guid('${keyVault.id}-${workspaceIndentityPrincipalId}-Key-Vault-Crypto-User') + properties: { + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + principalId: workspaceIndentityPrincipalId + principalType: 'ServicePrincipal' + } + scope: keyVault +} + +// Assign Acess Policy for Keys +resource workspace_cmk_accessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = if (!usesRbacAuthorization) { + name: 'add' + parent: keyVault + properties: { + accessPolicies: [ + { + permissions: { + keys: [ + 'wrapKey' + 'unwrapKey' + 'get' + ] + } + objectId: workspaceIndentityPrincipalId + tenantId: tenant().tenantId + } + ] + } +} diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..b057b0b981 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,31 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..56d89c1d0e --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,58 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep new file mode 100644 index 0000000000..ef593e0e43 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/dependencies.bicep @@ -0,0 +1,66 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the Key Vault Encryption Key.') +output keyVaultEncryptionKeyName string = keyVault::key.name + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep new file mode 100644 index 0000000000..4bb5a10444 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep @@ -0,0 +1,69 @@ +targetScope = 'subscription' + +metadata name = 'Using Customer-Managed-Keys with System-Assigned identity' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swensa' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + } + encryptionActivateWorkspace: true + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep new file mode 100644 index 0000000000..6faa37afac --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/dependencies.bicep @@ -0,0 +1,87 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Reader-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the Key Vault Encryption Key.') +output keyVaultEncryptionKeyName string = keyVault::key.name + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep new file mode 100644 index 0000000000..5e78e90a6b --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep @@ -0,0 +1,75 @@ +targetScope = 'subscription' + +metadata name = 'Using Customer-Managed-Keys with User-Assigned identity' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swenua' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + customerManagedKey: { + keyName: nestedDependencies.outputs.keyVaultEncryptionKeyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep new file mode 100644 index 0000000000..b057b0b981 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/dependencies.bicep @@ -0,0 +1,31 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep new file mode 100644 index 0000000000..608d9971f0 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -0,0 +1,70 @@ +targetScope = 'subscription' + + +metadata name = 'Using Managed Workspace Vnet' +metadata description = 'This instance deploys the module associating the workspace to a Managed workspace Virtual Netowork.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmanv' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + managedVirtualNetwork: true + preventDataExfiltration: true + allowedAadTenantIdsForLinking: [ + tenant().tenantId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..52da267176 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/max/dependencies.bicep @@ -0,0 +1,92 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.sql.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetworkName}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..0c97ffdb90 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep @@ -0,0 +1,135 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + location: location + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + initialWorkspaceAdminObjectID: nestedDependencies.outputs.managedIdentityPrincipalId + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + service: 'SQL' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + managedVirtualNetwork: true + integrationRuntimes: [ + { + type: 'SelfHosted' + name: 'shir01' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } +}] diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..52da267176 --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,92 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.sql.azuresynapse.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetworkName}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + isHnsEnabled: true + } + + resource blobService 'blobServices@2022-09-01' = { + name: 'default' + + resource container 'containers@2022-09-01' = { + name: 'synapsews' + } + } +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the created container.') +output storageContainerName string = storageAccount::blobService::container.name diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..aa0bada99a --- /dev/null +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,118 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-synapse.workspaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'swwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + location: location + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName + sqlAdministratorLogin: 'synwsadmin' + initialWorkspaceAdminObjectID: nestedDependencies.outputs.managedIdentityPrincipalId + managedIdentities: { + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + privateEndpoints: [ + { + subnetResourceId: nestedDependencies.outputs.subnetResourceId + service: 'SQL' + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + managedVirtualNetwork: true + integrationRuntimes: [ + { + type: 'SelfHosted' + name: 'shir01' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + logCategoriesAndGroups: [ + { + category: 'SynapseRbacOperations' + } + { + category: 'SynapseLinkEvent' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } +}] diff --git a/avm/res/synapse/workspace/version.json b/avm/res/synapse/workspace/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/synapse/workspace/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file From 8e2a043f481af4748ffc2907fbe7252343c1ed84 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 12:29:42 +0100 Subject: [PATCH 02/22] readme update --- avm/res/synapse/workspace/README.md | 5 +++ .../workspace/integration-runtime/README.md | 5 +++ avm/res/synapse/workspace/key/README.md | 28 +++------------ avm/res/synapse/workspace/key/main.bicep | 18 ---------- avm/res/synapse/workspace/key/main.json | 30 +--------------- avm/res/synapse/workspace/key/version.json | 7 ---- avm/res/synapse/workspace/main.bicep | 1 - avm/res/synapse/workspace/main.json | 35 ++----------------- 8 files changed, 18 insertions(+), 111 deletions(-) delete mode 100644 avm/res/synapse/workspace/key/version.json diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 74e737772b..460df079bf 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -9,6 +9,7 @@ This module deploys a Synapse Workspace. - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -1455,3 +1456,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | | `br/public:avm/res/network/private-endpoint:0.3.1` | Remote reference | + +## 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/synapse/workspace/integration-runtime/README.md b/avm/res/synapse/workspace/integration-runtime/README.md index 2f19cdc324..c5d6ab1ffd 100644 --- a/avm/res/synapse/workspace/integration-runtime/README.md +++ b/avm/res/synapse/workspace/integration-runtime/README.md @@ -8,6 +8,7 @@ This module deploys a Synapse Workspace Integration Runtime. - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -79,3 +80,7 @@ The name of the parent Synapse Workspace. Required if the template is used in a ## 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/synapse/workspace/key/README.md b/avm/res/synapse/workspace/key/README.md index 667aefb54b..68021da16a 100644 --- a/avm/res/synapse/workspace/key/README.md +++ b/avm/res/synapse/workspace/key/README.md @@ -8,6 +8,7 @@ This module deploys a Synapse Workspaces Key. - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -31,13 +32,6 @@ This module deploys a Synapse Workspaces Key. | :-- | :-- | :-- | | [`workspaceName`](#parameter-workspacename) | string | The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment. | -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | -| [`location`](#parameter-location) | string | The geo-location where the resource lives. | - ### Parameter: `isActiveCMK` Used to activate the workspace after a customer managed key is provided. @@ -66,22 +60,6 @@ The name of the parent Synapse Workspace. Required if the template is used in a - Required: Yes - Type: string -### Parameter: `enableDefaultTelemetry` - -Enable telemetry via a Globally Unique Identifier (GUID). - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `location` - -The geo-location where the resource lives. - -- Required: No -- Type: string -- Default: `[resourceGroup().location]` - ## Outputs @@ -94,3 +72,7 @@ The geo-location where the resource lives. ## 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/synapse/workspace/key/main.bicep b/avm/res/synapse/workspace/key/main.bicep index 7ae64222fc..e24333f15c 100644 --- a/avm/res/synapse/workspace/key/main.bicep +++ b/avm/res/synapse/workspace/key/main.bicep @@ -8,18 +8,12 @@ param name string @description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') param workspaceName string -@description('Optional. The geo-location where the resource lives.') -param location string = resourceGroup().location - @description('Required. Used to activate the workspace after a customer managed key is provided.') param isActiveCMK bool @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') param keyVaultResourceId string -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = { name: last(split(keyVaultResourceId, '/')) scope: resourceGroup(split(keyVaultResourceId, '/')[2], split(keyVaultResourceId, '/')[4]) @@ -42,18 +36,6 @@ resource key 'Microsoft.Synapse/workspaces/keys@2021-06-01' = { } } -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' - properties: { - mode: 'Incremental' - template: { - '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' - contentVersion: '1.0.0.0' - resources: [] - } - } -} - @description('The name of the deployed key.') output name string = key.name diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index 371874873e..92c63e6c99 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "17878422697036938783" + "templateHash": "10540991074684743146" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -24,13 +24,6 @@ "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The geo-location where the resource lives." - } - }, "isActiveCMK": { "type": "bool", "metadata": { @@ -42,13 +35,6 @@ "metadata": { "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } } }, "resources": [ @@ -60,20 +46,6 @@ "isActiveCMK": "[parameters('isActiveCMK')]", "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" } - }, - { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } } ], "outputs": { diff --git a/avm/res/synapse/workspace/key/version.json b/avm/res/synapse/workspace/key/version.json deleted file mode 100644 index 96236a61ba..0000000000 --- a/avm/res/synapse/workspace/key/version.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", - "pathFilters": [ - "./main.json" - ] -} diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 1a39ac0a28..c51050e803 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -224,7 +224,6 @@ module workspace_key 'key/main.bicep' = if (encryptionActivateWorkspace) { name: '${workspace.name}-cmk-activation' params: { name: customerManagedKey!.keyName - location: location isActiveCMK: true keyVaultResourceId: cMKKeyVault.id workspaceName: workspace.name diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index b294f7dc1b..fe4a41d39e 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "17529076065679517867" + "templateHash": "10745050092912187859" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -959,9 +959,6 @@ "name": { "value": "[parameters('customerManagedKey').keyName]" }, - "location": { - "value": "[parameters('location')]" - }, "isActiveCMK": { "value": true }, @@ -979,7 +976,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "17878422697036938783" + "templateHash": "10540991074684743146" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -998,13 +995,6 @@ "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The geo-location where the resource lives." - } - }, "isActiveCMK": { "type": "bool", "metadata": { @@ -1016,13 +1006,6 @@ "metadata": { "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } } }, "resources": [ @@ -1034,20 +1017,6 @@ "isActiveCMK": "[parameters('isActiveCMK')]", "keyVaultUrl": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('keyVaultResourceId'), '/')[2], split(parameters('keyVaultResourceId'), '/')[4]), 'Microsoft.KeyVault/vaults/keys', last(split(parameters('keyVaultResourceId'), '/')), parameters('name')), '2023-02-01').keyUri]" } - }, - { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } } ], "outputs": { From 53454b9974849600dcffab25e90365d33105fe2f Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 12:45:19 +0100 Subject: [PATCH 03/22] workflow --- .../workflows/avm.res.synapse.workspace.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.synapse.workspace.yml diff --git a/.github/workflows/avm.res.synapse.workspace.yml b/.github/workflows/avm.res.synapse.workspace.yml new file mode 100644 index 0000000000..c2ac52d276 --- /dev/null +++ b/.github/workflows/avm.res.synapse.workspace.yml @@ -0,0 +1,83 @@ +name: "avm.res.synapse.workspace" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.synapse.workspace.yml" + - "avm/res/synapse/workspace/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/synapse/workspace" + workflowPath: ".github/workflows/avm.res.synapse.workspace.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 497fd44338266452a870d4a41a4efa6dc0eda8d8 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 13:01:50 +0100 Subject: [PATCH 04/22] orphaned --- avm/res/synapse/workspace/ORPHANED.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 avm/res/synapse/workspace/ORPHANED.md diff --git a/avm/res/synapse/workspace/ORPHANED.md b/avm/res/synapse/workspace/ORPHANED.md new file mode 100644 index 0000000000..ef8fa911d2 --- /dev/null +++ b/avm/res/synapse/workspace/ORPHANED.md @@ -0,0 +1,4 @@ +⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ + +- Only security and bug fixes are being handled by the AVM core team at present. +- If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! \ No newline at end of file From ae7db52fef77afc238ee13c4c759153073200cc4 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 13:09:47 +0100 Subject: [PATCH 05/22] param update --- avm/res/synapse/workspace/README.md | 5 +++++ avm/res/synapse/workspace/key/README.md | 2 +- avm/res/synapse/workspace/key/main.bicep | 2 +- avm/res/synapse/workspace/key/main.json | 4 ++-- avm/res/synapse/workspace/main.json | 6 +++--- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 460df079bf..adfc9137d4 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1,5 +1,10 @@ # Synapse Workspaces `[Microsoft.Synapse/workspaces]` +> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ +> +> - Only security and bug fixes are being handled by the AVM core team at present. +> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! + This module deploys a Synapse Workspace. ## Navigation diff --git a/avm/res/synapse/workspace/key/README.md b/avm/res/synapse/workspace/key/README.md index 68021da16a..e38461c3c0 100644 --- a/avm/res/synapse/workspace/key/README.md +++ b/avm/res/synapse/workspace/key/README.md @@ -26,7 +26,7 @@ This module deploys a Synapse Workspaces Key. | [`keyVaultResourceId`](#parameter-keyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | | [`name`](#parameter-name) | string | Encryption key name. | -**Conditional parameters** +**Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | diff --git a/avm/res/synapse/workspace/key/main.bicep b/avm/res/synapse/workspace/key/main.bicep index e24333f15c..235dc77b82 100644 --- a/avm/res/synapse/workspace/key/main.bicep +++ b/avm/res/synapse/workspace/key/main.bicep @@ -5,7 +5,7 @@ metadata owner = 'Azure/module-maintainers' @description('Required. Encryption key name.') param name string -@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +@description('Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') param workspaceName string @description('Required. Used to activate the workspace after a customer managed key is provided.') diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index 92c63e6c99..b178a14d6b 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "10540991074684743146" + "templateHash": "1893962329691986346" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -21,7 +21,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "isActiveCMK": { diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index fe4a41d39e..19a29b46b1 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "10745050092912187859" + "templateHash": "14321734198796364988" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -976,7 +976,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "10540991074684743146" + "templateHash": "1893962329691986346" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -992,7 +992,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "isActiveCMK": { From f464cb6eaf5897a3aad41494f00d499b96244f95 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 16:12:26 +0100 Subject: [PATCH 06/22] codeowners, psrule --- .github/CODEOWNERS | 2 +- .../synapse/workspace/tests/e2e/waf-aligned/main.test.bicep | 5 +++++ avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4895ec9ead..8aafb203c3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,7 +132,7 @@ /avm/res/sql/server/ @Azure/avm-res-sql-server-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/storage/storage-account/ @Azure/avm-res-storage-storageaccount-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/synapse/private-link-hub/ @Azure/avm-res-synapse-privatelinkhub-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/synapse/workspace/ @Azure/avm-res-synapse-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/synapse/workspace/ @Azure/avm-res-synapse-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/virtual-machine-images/image-template/ @Azure/avm-res-virtualmachineimages-imagetemplate-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/web/connection/ @Azure/avm-res-web-connection-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/web/hosting-environment/ @Azure/avm-res-web-hostingenvironment-module-owners-bicep @Azure/avm-core-team-technical-bicep diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep index aa0bada99a..63caab0d8a 100644 --- a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -114,5 +114,10 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } }] diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml index 79f48d21af..19ef9d2eca 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml @@ -64,6 +64,7 @@ configuration: "secretid", "disablepassword", "sync*passwords", + "sqlAdministratorLogin", "tokenname", ] From 0643d1e31117f0d52862322c33f69f50eea8ca79 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 26 Jan 2024 16:27:19 +0100 Subject: [PATCH 07/22] tags --- avm/res/synapse/workspace/README.md | 12 ++++++++++++ avm/res/synapse/workspace/main.bicep | 2 +- .../pipelines/staticValidation/psrule/ps-rule.yaml | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index adfc9137d4..8fc6c35007 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -611,6 +611,11 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } } } ``` @@ -699,6 +704,13 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } } } } diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index c51050e803..c55e15e63f 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -55,11 +55,11 @@ param linkedAccessCheckOnTargetResource bool = false @description('Optional. Prevent Data Exfiltration.') param preventDataExfiltration bool = false - @allowed([ 'Enabled' 'Disabled' ]) + @description('Optional. Enable or Disable public network access to workspace.') param publicNetworkAccess string = 'Enabled' diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml index 19ef9d2eca..0cb7db9189 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml @@ -65,6 +65,7 @@ configuration: "disablepassword", "sync*passwords", "sqlAdministratorLogin", + "sqlAdministratorLoginPassword", "tokenname", ] From e491c55eefd0556a3ac0707544a6a9c1a41af6d7 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Tue, 30 Jan 2024 14:58:48 +0100 Subject: [PATCH 08/22] issue template update --- .github/ISSUE_TEMPLATE/avm_module_issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/avm_module_issue.yml b/.github/ISSUE_TEMPLATE/avm_module_issue.yml index 34c13fb9cb..ed9da33ce4 100644 --- a/.github/ISSUE_TEMPLATE/avm_module_issue.yml +++ b/.github/ISSUE_TEMPLATE/avm_module_issue.yml @@ -166,7 +166,7 @@ body: - "avm/res/sql/server" - "avm/res/storage/storage-account" # - "avm/res/synapse/private-link-hub" - # - "avm/res/synapse/workspace" + - "avm/res/synapse/workspace" # - "avm/res/virtual-machine-images/image-template" # - "avm/res/web/connection" # - "avm/res/web/hosting-environment" From ff807fec835d33ce6fe07a9537752fd78435d723 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Thu, 1 Feb 2024 12:06:09 +0100 Subject: [PATCH 09/22] workspace endpoint --- avm/res/synapse/workspace/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index c55e15e63f..686412e262 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -268,7 +268,7 @@ module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0. properties: { privateLinkServiceId: workspace.id groupIds: [ - privateEndpoint.?service ?? 'vault' + privateEndpoint.?service ?? 'workspaces' ] } } From 698b3e513cf7ae7354e99c451de098812eed4af4 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Thu, 1 Feb 2024 12:18:57 +0100 Subject: [PATCH 10/22] conditional changed --- avm/res/synapse/workspace/integration-runtime/main.bicep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/res/synapse/workspace/integration-runtime/main.bicep b/avm/res/synapse/workspace/integration-runtime/main.bicep index 2734626027..f6e878d08d 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.bicep +++ b/avm/res/synapse/workspace/integration-runtime/main.bicep @@ -2,7 +2,7 @@ metadata name = 'Synapse Workspace Integration Runtimes' metadata description = 'This module deploys a Synapse Workspace Integration Runtime.' metadata owner = 'Azure/module-maintainers' -@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +@description('Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') param workspaceName string @description('Required. The name of the Integration Runtime.') @@ -15,7 +15,7 @@ param name string @description('Required. The type of Integration Runtime.') param type string -@description('Conditional. Integration Runtime type properties. Required if type is "Managed".') +@description('Optional. Integration Runtime type properties. Required if type is "Managed".') param typeProperties object = {} resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { From 1ad2b08736543d499afa6aea3e0395cb714167c5 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Thu, 1 Feb 2024 12:21:26 +0100 Subject: [PATCH 11/22] readme update --- .../synapse/workspace/integration-runtime/README.md | 2 +- .../synapse/workspace/integration-runtime/main.json | 6 +++--- avm/res/synapse/workspace/main.json | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/avm/res/synapse/workspace/integration-runtime/README.md b/avm/res/synapse/workspace/integration-runtime/README.md index c5d6ab1ffd..8b93bf8565 100644 --- a/avm/res/synapse/workspace/integration-runtime/README.md +++ b/avm/res/synapse/workspace/integration-runtime/README.md @@ -25,7 +25,7 @@ This module deploys a Synapse Workspace Integration Runtime. | [`name`](#parameter-name) | string | The name of the Integration Runtime. | | [`type`](#parameter-type) | string | The type of Integration Runtime. | -**Conditional parameters** +**Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json index 94a7fe2f1b..b9a0ce0cff 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.json +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "2245322500910751784" + "templateHash": "556207760166596069" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -15,7 +15,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "name": { @@ -38,7 +38,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + "description": "Optional. Integration Runtime type properties. Required if type is \"Managed\"." } } }, diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 19a29b46b1..88793df457 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "14321734198796364988" + "templateHash": "13572549826340676103" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -790,7 +790,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "2245322500910751784" + "templateHash": "556207760166596069" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -800,7 +800,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "name": { @@ -823,7 +823,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." + "description": "Optional. Integration Runtime type properties. Required if type is \"Managed\"." } } }, @@ -1071,7 +1071,7 @@ "properties": { "privateLinkServiceId": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]", "groupIds": [ - "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'vault')]" + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'workspaces')]" ] } } From 391fff9f6944b5d18a5095a8afc5eb27e9849eb4 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Thu, 1 Feb 2024 13:18:50 +0100 Subject: [PATCH 12/22] synapse workspace module --- avm/res/synapse/workspace/README.md | 58 ++----------------- .../workspace/integration-runtime/README.md | 2 +- .../workspace/integration-runtime/main.bicep | 4 +- .../workspace/integration-runtime/main.json | 6 +- avm/res/synapse/workspace/key/README.md | 2 +- avm/res/synapse/workspace/key/main.bicep | 2 +- avm/res/synapse/workspace/key/main.json | 4 +- avm/res/synapse/workspace/main.bicep | 11 ++-- avm/res/synapse/workspace/main.json | 31 +++++----- .../tests/e2e/defaults/main.test.bicep | 2 - .../tests/e2e/encrwsai/main.test.bicep | 6 +- .../tests/e2e/encrwuai/main.test.bicep | 5 +- .../tests/e2e/managedvnet/main.test.bicep | 7 --- .../workspace/tests/e2e/max/main.test.bicep | 14 ++--- .../tests/e2e/waf-aligned/main.test.bicep | 19 ++---- 15 files changed, 54 insertions(+), 119 deletions(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 8fc6c35007..557169ea79 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1,10 +1,5 @@ # Synapse Workspaces `[Microsoft.Synapse/workspaces]` -> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ -> -> - Only security and bug fixes are being handled by the AVM core team at present. -> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! - This module deploys a Synapse Workspace. ## Navigation @@ -39,9 +34,9 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/res/synapse/workspace:`. - [Using only defaults](#example-1-using-only-defaults) -- [Using Customer-Managed-Keys with System-Assigned identity](#example-2-using-customer-managed-keys-with-system-assigned-identity) -- [Using Customer-Managed-Keys with User-Assigned identity](#example-3-using-customer-managed-keys-with-user-assigned-identity) -- [Using Managed Workspace Vnet](#example-4-using-managed-workspace-vnet) +- [Using encryption with Customer-Managed-Key](#example-2-using-encryption-with-customer-managed-key) +- [Using encryption with Customer-Managed-Key](#example-3-using-encryption-with-customer-managed-key) +- [Managedvnet](#example-4-managedvnet) - [Using large parameter set](#example-5-using-large-parameter-set) - [WAF-aligned](#example-6-waf-aligned) @@ -63,8 +58,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { defaultDataLakeStorageFilesystem: '' name: 'swmin001' sqlAdministratorLogin: 'synwsadmin' - // Non-required parameters - location: '' } } ``` @@ -93,10 +86,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { }, "sqlAdministratorLogin": { "value": "synwsadmin" - }, - // Non-required parameters - "location": { - "value": "" } } } @@ -105,7 +94,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {

-### Example 2: _Using Customer-Managed-Keys with System-Assigned identity_ +### Example 2: _Using encryption with Customer-Managed-Key_ This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret. @@ -129,7 +118,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { keyVaultResourceId: '' } encryptionActivateWorkspace: true - location: '' } } ``` @@ -168,9 +156,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { }, "encryptionActivateWorkspace": { "value": true - }, - "location": { - "value": "" } } } @@ -179,7 +164,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {

-### Example 3: _Using Customer-Managed-Keys with User-Assigned identity_ +### Example 3: _Using encryption with Customer-Managed-Key_ This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. @@ -203,7 +188,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { keyVaultResourceId: '' userAssignedIdentityResourceId: '' } - location: '' tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -246,9 +230,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { "userAssignedIdentityResourceId": "" } }, - "location": { - "value": "" - }, "tags": { "value": { "Environment": "Non-Prod", @@ -263,10 +244,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {

-### Example 4: _Using Managed Workspace Vnet_ - -This instance deploys the module associating the workspace to a Managed workspace Virtual Netowork. - +### Example 4: _Managedvnet_

@@ -285,7 +263,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { allowedAadTenantIdsForLinking: [ '' ] - location: '' managedVirtualNetwork: true preventDataExfiltration: true tags: { @@ -328,9 +305,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { "" ] }, - "location": { - "value": "" - }, "managedVirtualNetwork": { "value": true }, @@ -394,7 +368,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { type: 'SelfHosted' } ] - location: '' managedIdentities: { userAssignedResourceIds: [ '' @@ -492,9 +465,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } ] }, - "location": { - "value": "" - }, "managedIdentities": { "value": { "userAssignedResourceIds": [ @@ -590,7 +560,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { type: 'SelfHosted' } ] - location: '' managedIdentities: { userAssignedResourceIds: [ '' @@ -611,11 +580,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } } } ``` @@ -676,9 +640,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } ] }, - "location": { - "value": "" - }, "managedIdentities": { "value": { "userAssignedResourceIds": [ @@ -704,13 +665,6 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } } } } diff --git a/avm/res/synapse/workspace/integration-runtime/README.md b/avm/res/synapse/workspace/integration-runtime/README.md index 8b93bf8565..c5d6ab1ffd 100644 --- a/avm/res/synapse/workspace/integration-runtime/README.md +++ b/avm/res/synapse/workspace/integration-runtime/README.md @@ -25,7 +25,7 @@ This module deploys a Synapse Workspace Integration Runtime. | [`name`](#parameter-name) | string | The name of the Integration Runtime. | | [`type`](#parameter-type) | string | The type of Integration Runtime. | -**Optional parameters** +**Conditional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | diff --git a/avm/res/synapse/workspace/integration-runtime/main.bicep b/avm/res/synapse/workspace/integration-runtime/main.bicep index f6e878d08d..2734626027 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.bicep +++ b/avm/res/synapse/workspace/integration-runtime/main.bicep @@ -2,7 +2,7 @@ metadata name = 'Synapse Workspace Integration Runtimes' metadata description = 'This module deploys a Synapse Workspace Integration Runtime.' metadata owner = 'Azure/module-maintainers' -@description('Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') param workspaceName string @description('Required. The name of the Integration Runtime.') @@ -15,7 +15,7 @@ param name string @description('Required. The type of Integration Runtime.') param type string -@description('Optional. Integration Runtime type properties. Required if type is "Managed".') +@description('Conditional. Integration Runtime type properties. Required if type is "Managed".') param typeProperties object = {} resource workspace 'Microsoft.Synapse/workspaces@2021-06-01' existing = { diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json index b9a0ce0cff..94a7fe2f1b 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.json +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "556207760166596069" + "templateHash": "2245322500910751784" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -15,7 +15,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "name": { @@ -38,7 +38,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Optional. Integration Runtime type properties. Required if type is \"Managed\"." + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." } } }, diff --git a/avm/res/synapse/workspace/key/README.md b/avm/res/synapse/workspace/key/README.md index e38461c3c0..68021da16a 100644 --- a/avm/res/synapse/workspace/key/README.md +++ b/avm/res/synapse/workspace/key/README.md @@ -26,7 +26,7 @@ This module deploys a Synapse Workspaces Key. | [`keyVaultResourceId`](#parameter-keyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | | [`name`](#parameter-name) | string | Encryption key name. | -**Optional parameters** +**Conditional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | diff --git a/avm/res/synapse/workspace/key/main.bicep b/avm/res/synapse/workspace/key/main.bicep index 235dc77b82..e24333f15c 100644 --- a/avm/res/synapse/workspace/key/main.bicep +++ b/avm/res/synapse/workspace/key/main.bicep @@ -5,7 +5,7 @@ metadata owner = 'Azure/module-maintainers' @description('Required. Encryption key name.') param name string -@description('Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') +@description('Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment.') param workspaceName string @description('Required. Used to activate the workspace after a customer managed key is provided.') diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index b178a14d6b..92c63e6c99 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "1893962329691986346" + "templateHash": "10540991074684743146" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -21,7 +21,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "isActiveCMK": { diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 686412e262..c656f892b8 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -13,6 +13,9 @@ param location string = resourceGroup().location @description('Optional. Tags of the resource.') param tags object? +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + @description('Optional. Enable or Disable AzureADOnlyAuthentication on All Workspace sub-resource.') param azureADOnlyAuthentication bool = false @@ -28,9 +31,6 @@ param defaultDataLakeStorageFilesystem string @description('Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace\'s primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account.') param defaultDataLakeStorageCreateManagedPrivateEndpoint bool = false -@description('Optional. Enable/Disable usage telemetry for module.') -param enableTelemetry bool = true - @description('Optional. The customer managed key definition.') param customerManagedKey customerManagedKeyType @@ -55,11 +55,11 @@ param linkedAccessCheckOnTargetResource bool = false @description('Optional. Prevent Data Exfiltration.') param preventDataExfiltration bool = false + @allowed([ 'Enabled' 'Disabled' ]) - @description('Optional. Enable or Disable public network access to workspace.') param publicNetworkAccess string = 'Enabled' @@ -268,7 +268,7 @@ module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0. properties: { privateLinkServiceId: workspace.id groupIds: [ - privateEndpoint.?service ?? 'workspaces' + privateEndpoint.?service ?? 'SQL' ] } } @@ -286,6 +286,7 @@ module workspace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0. ipConfigurations: privateEndpoint.?ipConfigurations applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry } }] diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 88793df457..43d1e271ee 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "13572549826340676103" + "templateHash": "9288002267952533111" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -436,6 +436,13 @@ "description": "Optional. Tags of the resource." } }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, "azureADOnlyAuthentication": { "type": "bool", "defaultValue": false, @@ -469,13 +476,6 @@ "description": "Optional. Create managed private endpoint to the default storage account or not. If Yes is selected, a managed private endpoint connection request is sent to the workspace's primary Data Lake Storage Gen2 account for Spark pools to access data. This must be approved by an owner of the storage account." } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } - }, "customerManagedKey": { "$ref": "#/definitions/customerManagedKeyType", "metadata": { @@ -790,7 +790,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "556207760166596069" + "templateHash": "2245322500910751784" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -800,7 +800,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "name": { @@ -823,7 +823,7 @@ "type": "object", "defaultValue": {}, "metadata": { - "description": "Optional. Integration Runtime type properties. Required if type is \"Managed\"." + "description": "Conditional. Integration Runtime type properties. Required if type is \"Managed\"." } } }, @@ -976,7 +976,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "1893962329691986346" + "templateHash": "10540991074684743146" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", @@ -992,7 +992,7 @@ "workspaceName": { "type": "string", "metadata": { - "description": "Optional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Synapse Workspace. Required if the template is used in a standalone deployment." } }, "isActiveCMK": { @@ -1071,7 +1071,7 @@ "properties": { "privateLinkServiceId": "[resourceId('Microsoft.Synapse/workspaces', parameters('name'))]", "groupIds": [ - "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'workspaces')]" + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'SQL')]" ] } } @@ -1115,6 +1115,9 @@ }, "customNetworkInterfaceName": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "template": { diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep index 56d89c1d0e..b437972d81 100644 --- a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep @@ -36,7 +36,6 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } @@ -50,7 +49,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep index 4bb5a10444..9f73cb0d5f 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep @@ -1,8 +1,9 @@ targetScope = 'subscription' -metadata name = 'Using Customer-Managed-Keys with System-Assigned identity' +metadata name = 'Using encryption with Customer-Managed-Key' metadata description = 'This instance deploys the module using Customer-Managed-Keys using a System-Assigned Identity to access the Customer-Managed-Key secret.' + // ========== // // Parameters // // ========== // @@ -41,11 +42,9 @@ module nestedDependencies 'dependencies.bicep' = { // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } - // ============== // // Test Execution // // ============== // @@ -56,7 +55,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep index 5e78e90a6b..8aaf858f9c 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'subscription' -metadata name = 'Using Customer-Managed-Keys with User-Assigned identity' +metadata name = 'Using encryption with Customer-Managed-Key' metadata description = 'This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.' // ========== // @@ -42,11 +42,9 @@ module nestedDependencies 'dependencies.bicep' = { keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } - // ============== // // Test Execution // // ============== // @@ -57,7 +55,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep index 608d9971f0..f3b564cd2e 100644 --- a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -1,9 +1,5 @@ targetScope = 'subscription' - -metadata name = 'Using Managed Workspace Vnet' -metadata description = 'This instance deploys the module associating the workspace to a Managed workspace Virtual Netowork.' - // ========== // // Parameters // // ========== // @@ -37,11 +33,9 @@ module nestedDependencies 'dependencies.bicep' = { name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } - // ============== // // Test Execution // // ============== // @@ -52,7 +46,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep index 0c97ffdb90..c53fd56ca5 100644 --- a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep @@ -38,7 +38,6 @@ module nestedDependencies 'dependencies.bicep' = { managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } @@ -48,11 +47,11 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t scope: resourceGroup name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' params: { - location: location + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: location } } @@ -66,7 +65,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' @@ -95,11 +93,11 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ] privateEndpoints: [ { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - service: 'SQL' privateDnsZoneResourceIds: [ nestedDependencies.outputs.privateDNSZoneResourceId ] + service: 'SQL' + subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep index 63caab0d8a..5b1b67a5a0 100644 --- a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -38,7 +38,6 @@ module nestedDependencies 'dependencies.bicep' = { managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - location: location } } @@ -48,11 +47,11 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t scope: resourceGroup name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' params: { - location: location + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: location } } @@ -66,7 +65,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' - location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' @@ -78,11 +76,11 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } privateEndpoints: [ { - subnetResourceId: nestedDependencies.outputs.subnetResourceId - service: 'SQL' privateDnsZoneResourceIds: [ nestedDependencies.outputs.privateDNSZoneResourceId ] + service: 'SQL' + subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -114,10 +112,5 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } }] From 14b3f9d77d2b93fee1d3007f782f4af0af8c7daa Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 11:11:20 +0100 Subject: [PATCH 13/22] location --- avm/res/synapse/workspace/README.md | 31 +++++++++++++++++++ .../workspace/integration-runtime/main.json | 4 +-- avm/res/synapse/workspace/key/main.json | 4 +-- avm/res/synapse/workspace/main.json | 16 +++++----- .../tests/e2e/defaults/main.test.bicep | 2 ++ .../tests/e2e/encrwsai/main.test.bicep | 2 ++ .../tests/e2e/encrwuai/main.test.bicep | 2 ++ .../tests/e2e/managedvnet/main.test.bicep | 2 ++ .../workspace/tests/e2e/max/main.test.bicep | 2 ++ .../tests/e2e/waf-aligned/main.test.bicep | 2 ++ 10 files changed, 55 insertions(+), 12 deletions(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 557169ea79..5c7dd00d89 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1,5 +1,10 @@ # Synapse Workspaces `[Microsoft.Synapse/workspaces]` +> ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ +> +> - Only security and bug fixes are being handled by the AVM core team at present. +> - If interested in becoming the module owner of this orphaned module (must be Microsoft FTE), please look for the related "orphaned module" GitHub issue [here](https://aka.ms/AVM/OrphanedModules)! + This module deploys a Synapse Workspace. ## Navigation @@ -58,6 +63,8 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { defaultDataLakeStorageFilesystem: '' name: 'swmin001' sqlAdministratorLogin: 'synwsadmin' + // Non-required parameters + location: '' } } ``` @@ -86,6 +93,10 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { }, "sqlAdministratorLogin": { "value": "synwsadmin" + }, + // Non-required parameters + "location": { + "value": "" } } } @@ -118,6 +129,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { keyVaultResourceId: '' } encryptionActivateWorkspace: true + location: '' } } ``` @@ -156,6 +168,9 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { }, "encryptionActivateWorkspace": { "value": true + }, + "location": { + "value": "" } } } @@ -188,6 +203,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { keyVaultResourceId: '' userAssignedIdentityResourceId: '' } + location: '' tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -230,6 +246,9 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { "userAssignedIdentityResourceId": "" } }, + "location": { + "value": "" + }, "tags": { "value": { "Environment": "Non-Prod", @@ -263,6 +282,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { allowedAadTenantIdsForLinking: [ '' ] + location: '' managedVirtualNetwork: true preventDataExfiltration: true tags: { @@ -305,6 +325,9 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { "" ] }, + "location": { + "value": "" + }, "managedVirtualNetwork": { "value": true }, @@ -368,6 +391,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { type: 'SelfHosted' } ] + location: '' managedIdentities: { userAssignedResourceIds: [ '' @@ -465,6 +489,9 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } ] }, + "location": { + "value": "" + }, "managedIdentities": { "value": { "userAssignedResourceIds": [ @@ -560,6 +587,7 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { type: 'SelfHosted' } ] + location: '' managedIdentities: { userAssignedResourceIds: [ '' @@ -640,6 +668,9 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } ] }, + "location": { + "value": "" + }, "managedIdentities": { "value": { "userAssignedResourceIds": [ diff --git a/avm/res/synapse/workspace/integration-runtime/main.json b/avm/res/synapse/workspace/integration-runtime/main.json index 94a7fe2f1b..03114a39ba 100644 --- a/avm/res/synapse/workspace/integration-runtime/main.json +++ b/avm/res/synapse/workspace/integration-runtime/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2245322500910751784" + "version": "0.24.24.22086", + "templateHash": "5925144887906209420" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", diff --git a/avm/res/synapse/workspace/key/main.json b/avm/res/synapse/workspace/key/main.json index 92c63e6c99..f14f2c84df 100644 --- a/avm/res/synapse/workspace/key/main.json +++ b/avm/res/synapse/workspace/key/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "10540991074684743146" + "version": "0.24.24.22086", + "templateHash": "15811131631744837887" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 43d1e271ee..6c940bf0ef 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9288002267952533111" + "version": "0.24.24.22086", + "templateHash": "9311052963761588501" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -789,8 +789,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2245322500910751784" + "version": "0.24.24.22086", + "templateHash": "5925144887906209420" }, "name": "Synapse Workspace Integration Runtimes", "description": "This module deploys a Synapse Workspace Integration Runtime.", @@ -887,8 +887,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "1182711601328740781" + "version": "0.24.24.22086", + "templateHash": "17058954208193213785" } }, "parameters": { @@ -975,8 +975,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "10540991074684743146" + "version": "0.24.24.22086", + "templateHash": "15811131631744837887" }, "name": "Synapse Workspaces Keys", "description": "This module deploys a Synapse Workspaces Key.", diff --git a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep index b437972d81..1094f7b8df 100644 --- a/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/defaults/main.test.bicep @@ -35,6 +35,7 @@ module nestedDependencies 'dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { + location: location storageAccountName: 'dep${namePrefix}sa${serviceShort}01' } } @@ -49,6 +50,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep index 9f73cb0d5f..8bdbe890cb 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwsai/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location } } @@ -63,5 +64,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId } encryptionActivateWorkspace: true + location: location } }] diff --git a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep index 8aaf858f9c..09a99599d7 100644 --- a/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/encrwuai/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location } } @@ -55,6 +56,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep index f3b564cd2e..c6d952b428 100644 --- a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -32,6 +32,7 @@ module nestedDependencies 'dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { + location: location storageAccountName: 'dep${namePrefix}sa${serviceShort}01' } } @@ -46,6 +47,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep index c53fd56ca5..4b906a3af1 100644 --- a/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/max/main.test.bicep @@ -38,6 +38,7 @@ module nestedDependencies 'dependencies.bicep' = { managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + location: location } } @@ -65,6 +66,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep index 5b1b67a5a0..b5ee98aded 100644 --- a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -35,6 +35,7 @@ module nestedDependencies 'dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-nestedDependencies' params: { + location: location managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' storageAccountName: 'dep${namePrefix}sa${serviceShort}01' @@ -65,6 +66,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { name: '${namePrefix}${serviceShort}001' + location: location defaultDataLakeStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId defaultDataLakeStorageFilesystem: nestedDependencies.outputs.storageContainerName sqlAdministratorLogin: 'synwsadmin' From 0e71ae90643a1aada0802c43676a6d44b28ae1eb Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 11:27:18 +0100 Subject: [PATCH 14/22] dot end --- avm/res/synapse/workspace/main.bicep | 2 +- .../synapse/workspace/tests/e2e/managedvnet/main.test.bicep | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index c656f892b8..0c46bac236 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -358,7 +358,7 @@ type roleAssignmentType = { @description('Optional. The description of the role assignment.') description: string? - @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container"') + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') condition: string? @description('Optional. Version of the condition.') diff --git a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep index c6d952b428..210c80de70 100644 --- a/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/managedvnet/main.test.bicep @@ -1,5 +1,9 @@ targetScope = 'subscription' +metadata name = 'Using managed Vnet' +metadata description = 'This instance deploys the module using a managed Vnet.' + + // ========== // // Parameters // // ========== // From a769e0f14964e9f8ca38192ce3880834e375eb87 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 11:31:28 +0100 Subject: [PATCH 15/22] readme --- avm/res/synapse/workspace/README.md | 17 ++++++++++------- avm/res/synapse/workspace/main.json | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 5c7dd00d89..158e5221f7 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1,4 +1,4 @@ -# Synapse Workspaces `[Microsoft.Synapse/workspaces]` +# Synapse Workspaces `[Microsoft.synapse/workspace]` > ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ > @@ -41,7 +41,7 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Using encryption with Customer-Managed-Key](#example-2-using-encryption-with-customer-managed-key) - [Using encryption with Customer-Managed-Key](#example-3-using-encryption-with-customer-managed-key) -- [Managedvnet](#example-4-managedvnet) +- [Using managed Vnet](#example-4-using-managed-vnet) - [Using large parameter set](#example-5-using-large-parameter-set) - [WAF-aligned](#example-6-waf-aligned) @@ -263,7 +263,10 @@ module workspace 'br/public:avm/res/synapse/workspace:' = {

-### Example 4: _Managedvnet_ +### Example 4: _Using managed Vnet_ + +This instance deploys the module using a managed Vnet. +

@@ -1226,7 +1229,7 @@ Array of role assignments to create. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | | [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | @@ -1248,7 +1251,7 @@ The role to assign. You can provide either the display name of the role definiti ### Parameter: `privateEndpoints.roleAssignments.condition` -The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". - Required: No - Type: string @@ -1345,7 +1348,7 @@ Array of role assignments to create. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | | [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | @@ -1367,7 +1370,7 @@ The role to assign. You can provide either the display name of the role definiti ### Parameter: `roleAssignments.condition` -The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container" +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". - Required: No - Type: string diff --git a/avm/res/synapse/workspace/main.json b/avm/res/synapse/workspace/main.json index 6c940bf0ef..4fa53b6b04 100644 --- a/avm/res/synapse/workspace/main.json +++ b/avm/res/synapse/workspace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "9311052963761588501" + "templateHash": "6109386818166854532" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -95,7 +95,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." } }, "conditionVersion": { From 903277ca085fcc146fb3a99c48f31574313098a7 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 11:37:04 +0100 Subject: [PATCH 16/22] s to S --- avm/res/synapse/workspace/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 158e5221f7..8c40a6a56e 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -1,4 +1,4 @@ -# Synapse Workspaces `[Microsoft.synapse/workspace]` +# Synapse Workspaces `[Microsoft.Synapse/workspaces]` > ⚠️THIS MODULE IS CURRENTLY ORPHANED.⚠️ > From 5d5a6ff7e52e4b3d001adbaef5432654f53ad2dc Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 11:44:23 +0100 Subject: [PATCH 17/22] waf tags --- .../synapse/workspace/tests/e2e/waf-aligned/main.test.bicep | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep index b5ee98aded..8afb0453d5 100644 --- a/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/synapse/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -114,5 +114,10 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId } ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } } }] From 43ab977cc2c8867d429c29252091c1e8a2a10d38 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Fri, 2 Feb 2024 12:17:40 +0100 Subject: [PATCH 18/22] readme update --- avm/res/synapse/workspace/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/avm/res/synapse/workspace/README.md b/avm/res/synapse/workspace/README.md index 8c40a6a56e..7b27b03bae 100644 --- a/avm/res/synapse/workspace/README.md +++ b/avm/res/synapse/workspace/README.md @@ -611,6 +611,11 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } } } ``` @@ -699,6 +704,13 @@ module workspace 'br/public:avm/res/synapse/workspace:' = { } } ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } } } } From 17f5367e48469b61a77a1a9afd55d2bb5732b055 Mon Sep 17 00:00:00 2001 From: elisa anzelmo Date: Mon, 5 Feb 2024 09:54:59 +0100 Subject: [PATCH 19/22] Update .github/workflows/avm.res.synapse.workspace.yml Co-authored-by: Alexander Sehr --- .github/workflows/avm.res.synapse.workspace.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/avm.res.synapse.workspace.yml b/.github/workflows/avm.res.synapse.workspace.yml index c2ac52d276..411a93b005 100644 --- a/.github/workflows/avm.res.synapse.workspace.yml +++ b/.github/workflows/avm.res.synapse.workspace.yml @@ -72,6 +72,9 @@ jobs: ############################## call-workflow-passing-data: name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags needs: - job_initialize_pipeline uses: ./.github/workflows/avm.template.module.yml From bdd5cf5363fc0729665f16c9084ae9c052cb3838 Mon Sep 17 00:00:00 2001 From: elisa anzelmo Date: Mon, 5 Feb 2024 09:55:14 +0100 Subject: [PATCH 20/22] Update .github/workflows/avm.res.synapse.workspace.yml Co-authored-by: Alexander Sehr --- .github/workflows/avm.res.synapse.workspace.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/avm.res.synapse.workspace.yml b/.github/workflows/avm.res.synapse.workspace.yml index 411a93b005..518d3fc05c 100644 --- a/.github/workflows/avm.res.synapse.workspace.yml +++ b/.github/workflows/avm.res.synapse.workspace.yml @@ -20,7 +20,6 @@ on: description: "Remove deployed module" required: false default: true - push: branches: - main From 4f0bbaca3243931ab356f417c3787fe219e5f41f Mon Sep 17 00:00:00 2001 From: elisa anzelmo Date: Tue, 6 Feb 2024 12:02:47 +0100 Subject: [PATCH 21/22] Update avm/res/synapse/workspace/main.bicep Co-authored-by: Alexander Sehr --- avm/res/synapse/workspace/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 0c46bac236..5382df5c00 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -323,7 +323,7 @@ output resourceGroupName string = resourceGroup().name output connectivityEndpoints object = workspace.properties.connectivityEndpoints @description('The principal ID of the system assigned identity.') -output systemAssignedMIPrincipalId string = contains(workspace.identity, 'principalId') ? workspace.identity.principalId : '' +output systemAssignedMIPrincipalId string = workspace.?identity.?principalId ?? '' @description('The location the resource was deployed into.') output location string = workspace.location From 954bbdc283b372fc42376dbe553fb13fdd38dc50 Mon Sep 17 00:00:00 2001 From: Elisa Anzelmo Date: Tue, 6 Feb 2024 12:09:39 +0100 Subject: [PATCH 22/22] test with secret --- avm/res/synapse/workspace/main.bicep | 3 ++- avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/res/synapse/workspace/main.bicep b/avm/res/synapse/workspace/main.bicep index 5382df5c00..24b6c56f5b 100644 --- a/avm/res/synapse/workspace/main.bicep +++ b/avm/res/synapse/workspace/main.bicep @@ -70,7 +70,8 @@ param purviewResourceID string = '' param sqlAdministratorLogin string @description('Optional. Password for administrator access to the workspace\'s SQL pools. If you don\'t provide a password, one will be automatically generated. You can change the password later.') -#disable-next-line secure-secrets-in-params // Not a secret +//#disable-next-line secure-secrets-in-params // Not a secret +@secure() param sqlAdministratorLoginPassword string = '' @description('Optional. Git integration settings.') diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml index 0cb7db9189..19ef9d2eca 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml @@ -65,7 +65,6 @@ configuration: "disablepassword", "sync*passwords", "sqlAdministratorLogin", - "sqlAdministratorLoginPassword", "tokenname", ]