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
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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-05-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-02-01' = if (!empty(privateEndpoint_var.privateDnsZoneResourceIds)) {
name: '${privateEndpoint.name}/default'
properties: {
privateDnsZoneConfigs: [for j in range(0, length(privateEndpoint_var.privateDnsZoneResourceIds)): {
name: last(split(privateEndpoint_var.privateDnsZoneResourceIds[j], '/'))
properties: {
privateDnsZoneId: privateEndpoint_var.privateDnsZoneResourceIds[j]
}
}]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
]
},
"createMode": {
"value": "Recover"
"value": "Default"
},
"disableLocalAuth": {
"value": false
Expand All @@ -47,6 +47,14 @@
},
"softDeleteRetentionInDays": {
"value": 1
},
"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",
"service": "configurationStores"
}
]
}
}
}
13 changes: 13 additions & 0 deletions arm/Microsoft.AppConfiguration/configurationStores/deploy.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ param diagnosticMetricsToEnable array = [
@description('Optional. The name of the diagnostic setting, if deployed.')
param diagnosticSettingsName string = '${name}-diagnosticSettings'

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

var diagnosticsLogs = [for category in diagnosticLogCategoriesToEnable: {
category: category
enabled: true
Expand Down Expand Up @@ -185,6 +188,16 @@ module appConfiguration_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment,
}
}]

module appConfiguration_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (privateEndpoint, index) in privateEndpoints: {
name: '${uniqueString(deployment().name, location)}-AppConfig-PrivateEndpoint-${index}'
params: {
privateEndpointResourceId: appConfiguration.id
privateEndpointVnetLocation: empty(privateEndpoints) ? 'dummy' : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location
privateEndpointObj: privateEndpoint
tags: tags
}
}]

@description('The name of the app configuration.')
output name string = appConfiguration.name

Expand Down
39 changes: 39 additions & 0 deletions arm/Microsoft.AppConfiguration/configurationStores/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ This module deploys an App Configuration Store.
| `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) |

## Parameters

Expand All @@ -42,6 +44,7 @@ This module deploys an App Configuration Store.
| `enablePurgeProtection` | bool | `False` | | Property specifying whether protection against purge is enabled for this configuration store. |
| `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. |
| `publicNetworkAccess` | string | `'Enabled'` | `[Disabled, Enabled]` | Control permission for data plane traffic coming from public networks while private endpoint is enabled. |
| `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'. |
| `softDeleteRetentionInDays` | int | `1` | | The amount of time in days that the configuration store will be retained when it is soft deleted. |
Expand Down Expand Up @@ -106,6 +109,42 @@ Create a role assignment for the given resource. If you want to assign a service
}
```

### 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