Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions arm/Microsoft.Sql/servers/.bicep/nested_privateEndpoint.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@description('The resource ID of the service to link to')
param privateEndpointResourceId string

@description('Required. The location of the proviate endpoint')
param privateEndpointVnetLocation string

@description('Optional. Tags to add to the private endpoint.')
param tags object = {}

@description('Optional. The name of the private endpoint')
param name string = '${last(split(privateEndpointResourceId, '/'))}-${service}'

@description('Required. The service/groupId his private endpoint should connect to')
param service string = 'sqlServer'

@description('Required. Subnet in a virtual network resource.')
param subnetResourceId string

@description('Optional. Custom DNS configurations.')
param customDnsConfigs array = []

@description('Optional. A collection of private DNS zone configurations of the private dns zone group.')
param privateDnsZoneResourceIds array = []

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-05-01' = {
name: name
location: privateEndpointVnetLocation
tags: tags
properties: {
privateLinkServiceConnections: [
{
name: name
properties: {
privateLinkServiceId: privateEndpointResourceId
groupIds: [
service
]
}
}
]
subnet: {
id: subnetResourceId
}
customDnsConfigs: customDnsConfigs
}

resource privateDnsZoneGroups 'privateDnsZoneGroups@2021-02-01' = {
name: 'default'
properties: {
privateDnsZoneConfigs: [for privateDnsZoneResourceId in privateDnsZoneResourceIds: {
name: last(split(privateDnsZoneResourceId, '/'))
properties: {
privateDnsZoneId: privateDnsZoneResourceId
}
}]
}
}
}
7 changes: 7 additions & 0 deletions arm/Microsoft.Sql/servers/.parameters/parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@
"value": {
"/subscriptions/<<subscriptionId>>/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-<<namePrefix>>-az-msi-x-001": {}
}
},
"privateEndpoints": {
"value": [
{
"subnetResourceId": "/subscriptions/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<<namePrefix>>-az-vnet-x-001/subnets/<<namePrefix>>-az-subnet-x-005-privateEndpoints"
}
]
}
}
}
17 changes: 17 additions & 0 deletions arm/Microsoft.Sql/servers/deploy.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ param securityAlertPolicies array = []
@description('Conditional. The Azure Active Directory (AAD) administrator authentication. Required if no `administratorLogin` & `administratorLoginPassword` is provided.')
param administrators object = {}

@description('Optional. Configuration Details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.')
param privateEndpoints array = []

var identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None')

var identity = identityType != 'None' ? {
Expand Down Expand Up @@ -143,6 +146,20 @@ module server_databases 'databases/deploy.bicep' = [for (database, index) in dat
}
}]

module server_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (endpoint, index) in privateEndpoints: if (!empty(privateEndpoints)) {
name: '${uniqueString(deployment().name, location)}-Sql-PrivateEndpoints-${index}'
params: {
privateEndpointResourceId: server.id
privateEndpointVnetLocation: !empty(privateEndpoints) ? reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location : 'dummy'
service: contains(endpoint, 'service') ? endpoint.service : 'sqlServer'
subnetResourceId: endpoint.subnetResourceId
customDnsConfigs: contains(endpoint, 'customDnsConfigs') ? endpoint.customDnsConfigs : []
name: contains(endpoint, 'name') ? endpoint.name : '${last(split(server.id, '/'))}-sql'
privateDnsZoneResourceIds: contains(endpoint, 'privateDnsZoneResourceIds') ? endpoint.privateDnsZoneResourceIds : []
tags: contains(endpoint, 'tags') ? endpoint.tags : {}
}
}]

module server_firewallRules 'firewallRules/deploy.bicep' = [for (firewallRule, index) in firewallRules: {
name: '${uniqueString(deployment().name, location)}-Sql-FirewallRules-${index}'
params: {
Expand Down
39 changes: 39 additions & 0 deletions arm/Microsoft.Sql/servers/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This module deploys a SQL server.
| `Microsoft.Authorization/locks` | [2017-04-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) |
| `Microsoft.Authorization/roleAssignments` | [2020-10-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-10-01-preview/roleAssignments) |
| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) |
| `Microsoft.Network/privateEndpoints` | [2021-05-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) |
| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2021-02-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) |
| `Microsoft.Sql/servers` | [2021-05-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-05-01-preview/servers) |
| `Microsoft.Sql/servers/databases` | [2021-02-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-02-01-preview/servers/databases) |
| `Microsoft.Sql/servers/firewallRules` | [2021-05-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-05-01-preview/servers/firewallRules) |
Expand Down Expand Up @@ -43,6 +45,7 @@ This module deploys a SQL server.
| `firewallRules` | _[firewallRules](firewallRules/readme.md)_ array | `[]` | | The firewall rules to create in the server. |
| `location` | string | `[resourceGroup().location]` | | Location for all resources. |
| `lock` | string | `'NotSpecified'` | `[CanNotDelete, NotSpecified, ReadOnly]` | Specify the type of lock. |
| `privateEndpoints` | array | `[]` | | Configuration Details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. |
| `roleAssignments` | array | `[]` | | 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'. |
| `securityAlertPolicies` | _[securityAlertPolicies](securityAlertPolicies/readme.md)_ array | `[]` | | The security alert policies to create in the server. |
| `systemAssignedIdentity` | bool | `False` | | Enables system assigned managed identity on the resource. |
Expand Down Expand Up @@ -124,6 +127,42 @@ https://docs.microsoft.com/en-us/azure/templates/microsoft.sql/servers/administr
}
```

### 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/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
"service": "<<serviceName>>" // e.g. vault, registry, file, blob, queue, table etc.
"privateDnsZoneResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified
"/subscriptions/<<subscriptionId>>/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/<<subscriptionId>>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
"service": "<<serviceName>>" // e.g. vault, registry, file, blob, queue, table etc.
}
]
}
```

## Outputs

| Output Name | Type | Description |
Expand Down