From e090753568257a6e58889dc50f72c84d34bebacf Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Mon, 3 Jan 2022 15:51:53 +0100 Subject: [PATCH 1/6] Added support for Synapse Private Link Hubs --- .../workflows/ms.synapse.privatelinkhubs.yml | 146 ++++++++++++++++++ .vscode/settings.json | 82 +++++----- .../.bicep/nested_cuaId.bicep | 1 + arm/Microsoft.Synapse/deploy.bicep | 0 .../privateLinkHubs/.bicep/nested_cuaId.bicep | 1 + .../.parameters/parameters.json | 12 ++ .../privateLinkHubs/deploy.bicep | 22 +++ .../privateLinkHubs/readme.md | 0 arm/Microsoft.Synapse/readme.md | 0 arm/Microsoft.Synapse/workspaces/deploy.bicep | 0 arm/Microsoft.Synapse/workspaces/readme.md | 0 11 files changed, 222 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/ms.synapse.privatelinkhubs.yml create mode 100644 arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.Synapse/deploy.bicep create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/.parameters/parameters.json create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/readme.md create mode 100644 arm/Microsoft.Synapse/readme.md create mode 100644 arm/Microsoft.Synapse/workspaces/deploy.bicep create mode 100644 arm/Microsoft.Synapse/workspaces/readme.md diff --git a/.github/workflows/ms.synapse.privatelinkhubs.yml b/.github/workflows/ms.synapse.privatelinkhubs.yml new file mode 100644 index 0000000000..b1ee7e00fb --- /dev/null +++ b/.github/workflows/ms.synapse.privatelinkhubs.yml @@ -0,0 +1,146 @@ +name: 'Synapse: PrivateLinkHubs' + +on: + workflow_dispatch: + inputs: + removeDeployment: + type: boolean + description: 'Remove deployed module' + required: false + default: 'true' + versioningOption: + type: choice + description: 'The mode to handle the version increments [major|minor|patch]' + required: false + default: 'patch' + options: + - major + - minor + - patch + customVersion: + description: 'Custom version to apply. Used only if higher than latest' + required: false + default: '0.0.1' + push: + branches: + - main + paths: + - '.github/actions/templates/**' + - '.github/workflows/ms.synapse.privatelinkhubs.yml' + - 'arm/Microsoft.Synapse/privateLinkhHubs/**' + - '!*/**/readme.md' + - 'utilities/pipelines/**' + - '!utilities/pipelines/dependencies/**' + +env: + modulePath: 'arm/Microsoft.Synapse/privateLinkHubs' + workflowPath: '.github/workflows/ms.synapse.privatelinkhubs.yml' + AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} + ARM_SUBSCRIPTION_ID: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + ARM_MGMTGROUP_ID: '${{ secrets.ARM_MGMTGROUP_ID }}' + ARM_TENANT_ID: '${{ secrets.ARM_TENANT_ID }}' + DEPLOYMENT_SP_ID: '${{ secrets.DEPLOYMENT_SP_ID }}' + +jobs: + ############################ + # SET INPUT PARAMETERS # + ############################ + job_set_workflow_param: + runs-on: ubuntu-20.04 + name: 'Set input parameters to output variables' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Set input parameters' + id: get-workflow-param + uses: ./.github/actions/templates/getWorkflowInput + with: + workflowPath: '${{ env.workflowPath}}' + outputs: + removeDeployment: ${{ steps.get-workflow-param.outputs.removeDeployment }} + versioningOption: ${{ steps.get-workflow-param.outputs.versioningOption }} + customVersion: ${{ steps.get-workflow-param.outputs.customVersion }} + + #################### + # Pester Tests # + #################### + job_module_pester_validation: + runs-on: ubuntu-20.04 + name: 'Pester tests' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Run tests' + uses: ./.github/actions/templates/validateModulePester + with: + modulePath: '${{ env.modulePath }}' + + #################### + # Deployment tests # + #################### + job_module_deploy_validation: + runs-on: ubuntu-20.04 + name: 'Deployment tests' + needs: + - job_set_workflow_param + - job_module_pester_validation + strategy: + fail-fast: false + matrix: + parameterFilePaths: ['parameters.json'] + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: deep-mm/set-variables@v1.0 + with: + variableFileName: 'global.variables' + - name: 'Using parameter file [${{ matrix.parameterFilePaths }}]' + uses: ./.github/actions/templates/validateModuleDeployment + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + parameterFilePath: '${{ env.modulePath }}/.parameters/${{ matrix.parameterFilePaths }}' + location: '${{ env.defaultLocation }}' + resourceGroupName: '${{ env.resourceGroupName }}' + subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' + removeDeployment: '${{ needs.job_set_workflow_param.outputs.removeDeployment }}' + + ############### + # PUBLISH # + ############### + job_publish_module: + name: 'Publish module' + if: contains(fromJson('["refs/heads/main", "refs/heads/master"]'), github.ref) + runs-on: ubuntu-20.04 + needs: + - job_set_workflow_param + - job_module_deploy_validation + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: deep-mm/set-variables@v1.0 + with: + variableFileName: 'global.variables' + - name: 'Publish module' + uses: ./.github/actions/templates/publishModule + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + versioningOption: '${{ needs.job_set_workflow_param.outputs.versioningOption }}' + customVersion: '${{ needs.job_set_workflow_param.outputs.customVersion }}' + templateSpecsRGName: '${{ env.templateSpecsRGName }}' + templateSpecsRGLocation: '${{ env.templateSpecsRGLocation }}' + templateSpecsDescription: '${{ env.templateSpecsDescription }}' + templateSpecsDoPublish: '${{ env.templateSpecsDoPublish }}' + bicepRegistryName: '${{ env.bicepRegistryName }}' + bicepRegistryRGName: '${{ env.bicepRegistryRGName }}' + bicepRegistryDoPublish: '${{ env.bicepRegistryDoPublish }}' diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b56df2cb7..deea9cfa6c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,45 +1,43 @@ { - "[bicep]": { - "editor.insertSpaces": true, - "editor.tabSize": 2 - }, - "[markdown]": { - "files.encoding": "utf8" - }, - "[powershell]": { - "editor.insertSpaces": true, - "editor.tabSize": 4, - "files.encoding": "utf8bom" - }, - "[yaml]": { - "editor.insertSpaces": true, - "editor.tabSize": 2 - }, - "editor.formatOnPaste": true, - "editor.formatOnSave": true, + "[bicep]": { "editor.insertSpaces": true, - "files.insertFinalNewline": true, - "files.trimTrailingWhitespace": true, - "markdown.extension.orderedList.marker": "one", - "markdown.extension.tableFormatter.enabled": false, - "markdownlint.config": { - "MD034": true - }, - "powershell.codeFormatting.autoCorrectAliases": true, - "powershell.codeFormatting.newLineAfterCloseBrace": false, - "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline", - "powershell.codeFormatting.preset": "OTBS", - "powershell.codeFormatting.trimWhitespaceAroundPipe": true, - "powershell.codeFormatting.useConstantStrings": true, - "powershell.codeFormatting.useCorrectCasing": true, - "powershell.codeFormatting.whitespaceBetweenParameters": true, - "spellright.documentTypes": [ - "markdown", - "latex", - "plaintext" - ], - "spellright.language": [ - "en" - ], - "yaml.format.singleQuote": true + "editor.tabSize": 2 + }, + "[markdown]": { + "files.encoding": "utf8" + }, + "[powershell]": { + "editor.insertSpaces": true, + "editor.tabSize": 4, + "files.encoding": "utf8bom" + }, + "[yaml]": { + "editor.insertSpaces": true, + "editor.tabSize": 2 + }, + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "editor.insertSpaces": true, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "markdown.extension.orderedList.marker": "one", + "markdown.extension.tableFormatter.enabled": false, + "markdownlint.config": { + "MD034": true, + "MD028": false, + "MD025": { + "front_matter_title": "" + } + }, + "powershell.codeFormatting.autoCorrectAliases": true, + "powershell.codeFormatting.newLineAfterCloseBrace": false, + "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline", + "powershell.codeFormatting.preset": "OTBS", + "powershell.codeFormatting.trimWhitespaceAroundPipe": true, + "powershell.codeFormatting.useConstantStrings": true, + "powershell.codeFormatting.useCorrectCasing": true, + "powershell.codeFormatting.whitespaceBetweenParameters": true, + "spellright.documentTypes": ["markdown", "latex", "plaintext"], + "spellright.language": ["en"], + "yaml.format.singleQuote": true } diff --git a/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep b/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Synapse/deploy.bicep b/arm/Microsoft.Synapse/deploy.bicep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_cuaId.bicep b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Synapse/privateLinkHubs/.parameters/parameters.json b/arm/Microsoft.Synapse/privateLinkHubs/.parameters/parameters.json new file mode 100644 index 0000000000..a0b4b1c1b8 --- /dev/null +++ b/arm/Microsoft.Synapse/privateLinkHubs/.parameters/parameters.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "synplh0001" + }, + "location": { + "value": "westeurope" + } + } +} diff --git a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep new file mode 100644 index 0000000000..98f6a600b1 --- /dev/null +++ b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep @@ -0,0 +1,22 @@ +@description('Required. The name of the Private Link Hub.') +param name string = 'default' + +@description('Required. The geo-location where the resource lives.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object = {} + +var uniqueName = '${uniqueString('synplh${deployment().name}')}' + +resource synapse_privateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { + name: (empty(name)) ? uniqueName : name + location: location + tags: tags +} + +@description('The resource ID of the deployed Synapse Private Link Hub.') +output SynapsePrivateLinkHubResourceId string = synapse_privateLinkHub.id + +@description('The name of the deployed Synapse Private Link Hub.') +output SynapsePrivateLinkHubName string = synapse_privateLinkHub.name diff --git a/arm/Microsoft.Synapse/privateLinkHubs/readme.md b/arm/Microsoft.Synapse/privateLinkHubs/readme.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arm/Microsoft.Synapse/readme.md b/arm/Microsoft.Synapse/readme.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arm/Microsoft.Synapse/workspaces/deploy.bicep b/arm/Microsoft.Synapse/workspaces/deploy.bicep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arm/Microsoft.Synapse/workspaces/readme.md b/arm/Microsoft.Synapse/workspaces/readme.md new file mode 100644 index 0000000000..e69de29bb2 From b28e94963a7d3723a68272162cc1eb01bcbfbabe Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Mon, 3 Jan 2022 16:04:07 +0100 Subject: [PATCH 2/6] Fixed typo in Github workflow --- .github/workflows/ms.synapse.privatelinkhubs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ms.synapse.privatelinkhubs.yml b/.github/workflows/ms.synapse.privatelinkhubs.yml index b1ee7e00fb..40de20d464 100644 --- a/.github/workflows/ms.synapse.privatelinkhubs.yml +++ b/.github/workflows/ms.synapse.privatelinkhubs.yml @@ -27,7 +27,7 @@ on: paths: - '.github/actions/templates/**' - '.github/workflows/ms.synapse.privatelinkhubs.yml' - - 'arm/Microsoft.Synapse/privateLinkhHubs/**' + - 'arm/Microsoft.Synapse/privateLinkHubs/**' - '!*/**/readme.md' - 'utilities/pipelines/**' - '!utilities/pipelines/dependencies/**' From 9ceb44fe41321c9e9cbb7bbc0af7b4e04d4bbc7a Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Tue, 4 Jan 2022 10:14:57 +0100 Subject: [PATCH 3/6] Create new workflow for deploying Synapse Private Link Hub --- .github/workflows/ms.synapse.privatelinkhubs.yml | 2 +- arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep | 1 - arm/Microsoft.Synapse/deploy.bicep | 0 arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep | 6 ++---- arm/Microsoft.Synapse/readme.md | 0 arm/Microsoft.Synapse/workspaces/deploy.bicep | 0 arm/Microsoft.Synapse/workspaces/readme.md | 0 7 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep delete mode 100644 arm/Microsoft.Synapse/deploy.bicep delete mode 100644 arm/Microsoft.Synapse/readme.md delete mode 100644 arm/Microsoft.Synapse/workspaces/deploy.bicep delete mode 100644 arm/Microsoft.Synapse/workspaces/readme.md diff --git a/.github/workflows/ms.synapse.privatelinkhubs.yml b/.github/workflows/ms.synapse.privatelinkhubs.yml index 40de20d464..ad182d9e4c 100644 --- a/.github/workflows/ms.synapse.privatelinkhubs.yml +++ b/.github/workflows/ms.synapse.privatelinkhubs.yml @@ -23,7 +23,7 @@ on: default: '0.0.1' push: branches: - - main + - users/repajta/852_synapse_template paths: - '.github/actions/templates/**' - '.github/workflows/ms.synapse.privatelinkhubs.yml' diff --git a/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep b/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep deleted file mode 100644 index 8b13789179..0000000000 --- a/arm/Microsoft.Synapse/.bicep/nested_cuaId.bicep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/arm/Microsoft.Synapse/deploy.bicep b/arm/Microsoft.Synapse/deploy.bicep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep index 98f6a600b1..465ee48687 100644 --- a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep +++ b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep @@ -1,5 +1,5 @@ @description('Required. The name of the Private Link Hub.') -param name string = 'default' +param name string @description('Required. The geo-location where the resource lives.') param location string = resourceGroup().location @@ -7,10 +7,8 @@ param location string = resourceGroup().location @description('Optional. Tags of the resource.') param tags object = {} -var uniqueName = '${uniqueString('synplh${deployment().name}')}' - resource synapse_privateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { - name: (empty(name)) ? uniqueName : name + name: name location: location tags: tags } diff --git a/arm/Microsoft.Synapse/readme.md b/arm/Microsoft.Synapse/readme.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/arm/Microsoft.Synapse/workspaces/deploy.bicep b/arm/Microsoft.Synapse/workspaces/deploy.bicep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/arm/Microsoft.Synapse/workspaces/readme.md b/arm/Microsoft.Synapse/workspaces/readme.md deleted file mode 100644 index e69de29bb2..0000000000 From 33153b8bcc4ae970271776abd08a5c0aaecf71e2 Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Tue, 4 Jan 2022 13:19:56 +0100 Subject: [PATCH 4/6] Added support for Locks, RBAC and Private Endpoints --- .../.bicep/nested_privateEndpoint.bicep | 50 ++++++++++++++++++ .../privateLinkHubs/.bicep/nested_rbac.bicep | 32 ++++++++++++ .../privateLinkHubs/deploy.bicep | 51 +++++++++++++++++-- 3 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_privateEndpoint.bicep create mode 100644 arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_rbac.bicep diff --git a/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_privateEndpoint.bicep b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_privateEndpoint.bicep new file mode 100644 index 0000000000..a65adc0f7d --- /dev/null +++ b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_privateEndpoint.bicep @@ -0,0 +1,50 @@ +param privateEndpointResourceId string +param privateEndpointVnetLocation string +param privateEndpointObj object +param tags object + +var privateEndpointResourceName = last(split(privateEndpointResourceId, '/')) +var privateEndpoint_var = { + name: contains(privateEndpointObj, 'name') ? (empty(privateEndpointObj.name) ? '${privateEndpointResourceName}-${privateEndpointObj.service}' : privateEndpointObj.name) : '${privateEndpointResourceName}-${privateEndpointObj.service}' + subnetResourceId: privateEndpointObj.subnetResourceId + service: [ + privateEndpointObj.service + ] + privateDnsZoneResourceIds: contains(privateEndpointObj, 'privateDnsZoneResourceIds') ? (empty(privateEndpointObj.privateDnsZoneResourceIds) ? [] : privateEndpointObj.privateDnsZoneResourceIds) : [] + customDnsConfigs: contains(privateEndpointObj, 'customDnsConfigs') ? (empty(privateEndpointObj.customDnsConfigs) ? null : privateEndpointObj.customDnsConfigs) : null +} + +resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-03-01' = { + name: privateEndpoint_var.name + location: privateEndpointVnetLocation + tags: tags + properties: { + privateLinkServiceConnections: [ + { + name: privateEndpoint_var.name + properties: { + privateLinkServiceId: privateEndpointResourceId + groupIds: privateEndpoint_var.service + } + } + ] + manualPrivateLinkServiceConnections: [] + subnet: { + id: privateEndpoint_var.subnetResourceId + } + customDnsConfigs: privateEndpoint_var.customDnsConfigs + } +} + +resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2021-03-01' = if (!empty(privateEndpoint_var.privateDnsZoneResourceIds)) { + name: 'default' + properties: { + privateDnsZoneConfigs: [for privateDnsZoneResourceId in privateEndpoint_var.privateDnsZoneResourceIds: { + name: last(split(privateDnsZoneResourceId, '/')) + properties: { + privateDnsZoneId: privateDnsZoneResourceId + } + }] + } + parent: privateEndpoint +} diff --git a/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_rbac.bicep b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..219a778163 --- /dev/null +++ b/arm/Microsoft.Synapse/privateLinkHubs/.bicep/nested_rbac.bicep @@ -0,0 +1,32 @@ +param principalIds array +param roleDefinitionIdOrName string +param resourceId string + +var builtInRoleNames = { + 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource synapsePrivateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' existing = { + name: last(split(resourceId, '/')) +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = [for principalId in principalIds: { + name: guid(synapsePrivateLinkHub.name, principalId, roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + } + scope: synapsePrivateLinkHub +}] diff --git a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep index 465ee48687..38cfc891f2 100644 --- a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep +++ b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep @@ -7,14 +7,59 @@ param location string = resourceGroup().location @description('Optional. Tags of the resource.') param tags object = {} -resource synapse_privateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { +@allowed([ + 'CanNotDelete' + 'NotSpecified' + 'ReadOnly' +]) +@description('Optional. Specify the type of lock.') +param lock string = 'NotSpecified' + +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') +param roleAssignments array = [] + +@description('Optional. Configuration Details for private endpoints.') +param privateEndpoints array = [] + +resource synapsePrivateLinkHub 'Microsoft.Synapse/privateLinkHubs@2021-06-01' = { name: name location: location tags: tags } +// Resource Lock +resource synapsePrivateLinkHub_lock 'Microsoft.Authorization/locks@2016-09-01' = if (lock != 'NotSpecified') { + name: '${synapsePrivateLinkHub.name}-${lock}-lock' + properties: { + level: lock + notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + } + scope: synapsePrivateLinkHub +} + +// RBAC +module synapsePrivateLinkHub_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${deployment().name}-rbac-${index}' + params: { + principalIds: roleAssignment.principalIds + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + resourceId: synapsePrivateLinkHub.id + } +}] + +// Private Endpoints +module synapsePrivateLinkHub_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (privateEndpoint, index) in privateEndpoints: { + name: '${uniqueString(deployment().name, location)}-PrivateEndpoint-${index}' + params: { + privateEndpointResourceId: synapsePrivateLinkHub.id + privateEndpointVnetLocation: reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + privateEndpointObj: privateEndpoint + tags: tags + } +}] + @description('The resource ID of the deployed Synapse Private Link Hub.') -output SynapsePrivateLinkHubResourceId string = synapse_privateLinkHub.id +output synapsePrivateLinkHubResourceId string = synapsePrivateLinkHub.id @description('The name of the deployed Synapse Private Link Hub.') -output SynapsePrivateLinkHubName string = synapse_privateLinkHub.name +output synapsePrivateLinkHubName string = synapsePrivateLinkHub.name From 91e836aaf5a8988c29c876e072d1229348dce77c Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Tue, 4 Jan 2022 13:51:12 +0100 Subject: [PATCH 5/6] Updated ReadMe file --- .../privateLinkHubs/readme.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/arm/Microsoft.Synapse/privateLinkHubs/readme.md b/arm/Microsoft.Synapse/privateLinkHubs/readme.md index e69de29bb2..cca6932d08 100644 --- a/arm/Microsoft.Synapse/privateLinkHubs/readme.md +++ b/arm/Microsoft.Synapse/privateLinkHubs/readme.md @@ -0,0 +1,119 @@ +# Synapse PrivateLinkHubs `[Microsoft.Synapse/privateLinkHubs]` + +This module deploys Synapse PrivateLinkHubs. +// TODO: Replace Resource and fill in description + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | 2016-09-01 | +| `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Network/privateEndpoints` | 2021-03-01 | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | 2021-03-01 | +| `Microsoft.Synapse/privateLinkHubs` | 2021-06-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `location` | string | `[resourceGroup().location]` | | Required. The geo-location where the resource lives. | +| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. | +| `name` | string | | | Required. The name of the Private Link Hub. | +| `privateEndpoints` | array | `[]` | | Optional. Configuration Details for private endpoints. | +| `roleAssignments` | array | `[]` | | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | +| `tags` | object | `{object}` | | Optional. Tags of the resource. | + +### Parameter Usage: `` + +// TODO: Fill in Parameter usage + +### Parameter Usage: `privateEndpoints` + +To use Private Endpoint the following dependencies must be deployed: + +- Destination subnet must be created with the following configuration option - `"privateEndpointNetworkPolicies": "Disabled"`. Setting this option acknowledges that NSG rules are not applied to Private Endpoints (this capability is coming soon). A full example is available in the Virtual Network Module. +- Although not strictly required, it is highly recommended to first create a private DNS Zone to host Private Endpoint DNS records. See [Azure Private Endpoint DNS configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns) for more information. + +```json +"privateEndpoints": { + "value": [ + // Example showing all available fields + { + "name": "sxx-az-pe", // Optional: Name will be automatically generated if one is not provided here + "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001", + "service": "blob", + "privateDnsZoneResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified + "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net" + ], + "customDnsConfigs": [ // Optional + { + "fqdn": "customname.test.local", + "ipAddresses": [ + "10.10.10.10" + ] + } + ] + }, + // Example showing only mandatory fields + { + "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001", + "service": "file" + } + ] +} +``` + +### Parameter Usage: `roleAssignments` + +```json +"roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "12345678-1234-1234-1234-123456789012", // object 1 + "78945612-1234-1234-1234-123456789012" // object 2 + ] + }, + { + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11", + "principalIds": [ + "12345678-1234-1234-1234-123456789012" // object 1 + ] + } + ] +} +``` + +### Parameter Usage: `tags` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +```json +"tags": { + "value": { + "Environment": "Non-Prod", + "Contact": "test.user@testcompany.com", + "PurchaseOrder": "1234", + "CostCenter": "7890", + "ServiceName": "DeploymentValidation", + "Role": "DeploymentValidation" + } +} +``` + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `synapsePrivateLinkHubName` | string | The name of the deployed Synapse Private Link Hub. | +| `synapsePrivateLinkHubResourceId` | string | The resource ID of the deployed Synapse Private Link Hub. | + +## Template references + +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/privateEndpoints) +- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/privateEndpoints/privateDnsZoneGroups) +- [Privatelinkhubs](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Synapse/2021-06-01/privateLinkHubs) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) From 397a443663be0a59b7b37b449ab65f57d3428296 Mon Sep 17 00:00:00 2001 From: Rene Pajta Date: Tue, 4 Jan 2022 13:53:35 +0100 Subject: [PATCH 6/6] Fixed outputs & updated ReadMe --- arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep | 3 +++ arm/Microsoft.Synapse/privateLinkHubs/readme.md | 1 + 2 files changed, 4 insertions(+) diff --git a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep index 38cfc891f2..be450168a2 100644 --- a/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep +++ b/arm/Microsoft.Synapse/privateLinkHubs/deploy.bicep @@ -63,3 +63,6 @@ output synapsePrivateLinkHubResourceId string = synapsePrivateLinkHub.id @description('The name of the deployed Synapse Private Link Hub.') output synapsePrivateLinkHubName string = synapsePrivateLinkHub.name + +@description('The resource group of the deployed Synapse Private Link Hub.') +output synapsePrivateLinkHubResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.Synapse/privateLinkHubs/readme.md b/arm/Microsoft.Synapse/privateLinkHubs/readme.md index cca6932d08..dd4361e14f 100644 --- a/arm/Microsoft.Synapse/privateLinkHubs/readme.md +++ b/arm/Microsoft.Synapse/privateLinkHubs/readme.md @@ -108,6 +108,7 @@ Tag names and tag values can be provided as needed. A tag can be left without a | Output Name | Type | Description | | :-- | :-- | :-- | | `synapsePrivateLinkHubName` | string | The name of the deployed Synapse Private Link Hub. | +| `synapsePrivateLinkHubResourceGroup` | string | The resource group of the deployed Synapse Private Link Hub. | | `synapsePrivateLinkHubResourceId` | string | The resource ID of the deployed Synapse Private Link Hub. | ## Template references