Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private Endpoint for App Service #144

Merged
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
46 changes: 46 additions & 0 deletions azresources/compute/web/appservice-linux-container.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ param aiIKey string
@description('Virtual Network Integration Subnet Resource Id.')
param vnetIntegrationSubnetId string

@description('Whether to deploy private endpoint for inbound traffic')
param enablePrivateEndpoint bool

@description('Private DNS Zone Resource Id.')
param privateZoneId string

@description('Private endpoint subnet ID')
param privateEndpointSubnetId string


// Linux Web App with Virtual Network Integration
resource app 'Microsoft.Web/sites@2021-02-01' = {
name: name
Expand Down Expand Up @@ -74,3 +84,39 @@ resource app 'Microsoft.Web/sites@2021-02-01' = {
}
}
}


resource appservice_linuxcontainer_pe 'Microsoft.Network/privateEndpoints@2020-06-01' = if (enablePrivateEndpoint) {
location: resourceGroup().location
name: '${app.name}-endpoint'
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: '${app.name}-endpoint'
properties: {
privateLinkServiceId: app.id
groupIds: [
'sites'
]
}
}
]
}

resource appservice_pe_dns_reg 'privateDnsZoneGroups@2020-06-01' = {
name: 'default'
properties: {
privateDnsZoneConfigs: [
{
name: 'privatelink_azure_websites_net'
properties: {
privateDnsZoneId: privateZoneId
}
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
11 changes: 6 additions & 5 deletions docs/archetypes/machinelearning.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ Subscription can be moved to a target Management Group through Azure ARM Templat
| Monitoring | Application Insights - Application performance and monitoring cloud service | - | [Azure Docs](https://docs.microsoft.com/azure/azure-monitor/app/app-insights-overview)


> For App Service, for using the SKU tier `Premium` to support private endpoints, it may require a quota increase.

The intended cloud service workflows and data movements for this archetype include:

1. Data can be ingested from various sources using Data Factory, which uses managed virtual network for its Azure hosted integration runtime.
Expand Down Expand Up @@ -131,10 +129,12 @@ Once the machine learning archetype is deployed and available to use, access con
| Azure Storage Account for Azure ML | Network ACL deny | Private endpoint on `blob`, `file` + DNS registration to either hub or spoke | `privateEndpoints`|
| Azure Data Factory | Public network access disabled, Azure integration runtime with managed virtual network | Private endpoint on `dataFactory` + DNS registration to either hub or spoke | `privateEndpoints`|
| Azure Kubernetes Service | Private cluster, network profile set with either kubenet or Azure CNI | N/A | `aks`|
| Azure App Service | Virtual Network integration | N/A | `appService` |
| Azure App Service | Virtual Network integration. Public network access can be disabled, using private endpoint instead | Private endpoint on `azureWebsites` + DNS registration to either hub or spoke | `appService`, `privateEndpoints` |
hudua marked this conversation as resolved.
Show resolved Hide resolved
| Azure Container Registry | Network ACL deny, public network access disabled | Private endpoint on `registry` + DNS registration to either hub or spoke | `privateEndpoints`|f
| Azure Application Insights | N/A | N/A | N/A |

> For App Service, private endpoint requires the SKU tier `Premium`: https://docs.microsoft.com/azure/app-service/networking/private-endpoint so this may require a quota increase.

This archetype also has the following security features as options for deployment:

* Customer managed keys for encryption at rest, including Azure ML, storage, Container Registry, Data Factory, SQL Database / Managed Instance, and Kubernetes Service.
Expand Down Expand Up @@ -272,7 +272,7 @@ Reference implementation uses parameter files with `object` parameters to consol
| Deployment with AKS using Network Plugin: Azure CNI + Network Policy: Calico | [tests/schemas/lz-machinelearning/AKS-AzureCNI-Calico.json](../../tests/schemas/lz-machinelearning/AKS-AzureCNI-Calico.json) | `parameters.aks.value.networkPlugin` equals ***azure***, `parameters.aks.value.networkPlugin` equals ***calico***, `parameters.aks.value.podCidr` is ***empty***, `parameters.aks.value.serviceCidr` is filled, `parameters.aks.value.dnsServiceIP` is filled and `parameters.aks.value.dockerBridgeCidr` is filled |
| Deployment with AKS using Network Plugin: Azure CNI + Network Policy: Azure | [tests/schemas/lz-machinelearning/AKS-AzureCNI-AzureNP.json](../../tests/schemas/lz-machinelearning/AKS-AzureCNI-AzureNP.json) | `parameters.aks.value.networkPlugin` equals ***azure***, `parameters.aks.value.networkPlugin` equals ***azure***, `parameters.aks.value.podCidr` is ***empty***, `parameters.aks.value.serviceCidr` is filled, `parameters.aks.value.dnsServiceIP` is filled and `parameters.aks.value.dockerBridgeCidr` is filled |
| Deployment without Azure App Service for Linux Containers | [tests/schemas/lz-machinelearning/AppServiceLinuxContainerIsFalse.json](../../tests/schemas/lz-machinelearning/AppServiceLinuxContainerIsFalse.json) | `parameters.appServiceLinuxContainer.value.enabled` is false. |

| Deployment with Azure App Service for Linux Containers without Private Endpoint| [tests/schemas/lz-machinelearning/AppServiceLinuxContainerPrivateEndpointIsFalse.json](../../tests/schemas/lz-machinelearning/AppServiceLinuxContainerPrivateEndpointIsFalse.json) | `parameters.appServiceLinuxContainer.value.enabled` is true, `parameters.appServiceLinuxContainer.value.sku{Name,Tier}` are filled, and `parameters.appServiceLinuxContainer.value.enablePrivateEndpoint` is false. |
### Example Deployment Parameters

This example configures:
Expand Down Expand Up @@ -418,7 +418,8 @@ This example configures:
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"aml": {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion landingzones/lz-machinelearning/lz.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,10 @@ module appServiceLC '../../azresources/compute/web/appservice-linux-container.bi
storageId: dataLakeMetaData.outputs.storageId

vnetIntegrationSubnetId: networking.outputs.appServiceSubnetId

enablePrivateEndpoint: appServiceLinuxContainer.enablePrivateEndpoint
privateEndpointSubnetId: networking.outputs.privateEndpointSubnetId
privateZoneId: networking.outputs.asPrivateDnsZoneId

tags: resourceTags
}
}
Expand Down
16 changes: 16 additions & 0 deletions landingzones/lz-machinelearning/networking.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,21 @@ module privatezone_acr '../../azresources/network/private-dns-zone.bicep' = {
}
}

module privatezone_as '../../azresources/network/private-dns-zone.bicep' = {
name: 'deploy-privatezone-as'
scope: resourceGroup()
params: {
zone: 'privatelink.azurewebsites.net'
vnetId: vnet.id

dnsCreateNewZone: !hubNetwork.privateDnsManagedByHub
dnsLinkToVirtualNetwork: !hubNetwork.privateDnsManagedByHub || (hubNetwork.privateDnsManagedByHub && !usingCustomDNSServers)
dnsExistingZoneSubscriptionId: hubNetwork.privateDnsManagedByHubSubscriptionId
dnsExistingZoneResourceGroupName: hubNetwork.privateDnsManagedByHubResourceGroupName
registrationEnabled: false
}
}

module privatezone_datalake_blob '../../azresources/network/private-dns-zone.bicep' = {
name: 'deploy-privatezone-blob'
scope: resourceGroup()
Expand Down Expand Up @@ -698,5 +713,6 @@ output sqlDBPrivateDnsZoneId string = privatezone_sqldb.outputs.privateDnsZoneId
output amlApiPrivateDnsZoneId string = privatezone_azureml_api.outputs.privateDnsZoneId
output amlNotebooksPrivateDnsZoneId string = privatezone_azureml_notebook.outputs.privateDnsZoneId
output aksPrivateDnsZoneId string = privatezone_aks.outputs.privateDnsZoneId
output asPrivateDnsZoneId string = privatezone_as.outputs.privateDnsZoneId

output aksUdrNAme string = udrAKS.name
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@
},
"skuTier": {
"type": "string"
},
"enablePrivateEndpoint": {
"type": "boolean",
"enum": [
true,
false
]
}
},
"required": [
"enabled",
"skuName",
"skuTier"
"skuTier",
"enablePrivateEndpoint"
]
},
{
Expand Down
12 changes: 12 additions & 0 deletions schemas/latest/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## Landing Zone Schemas

### January 16, 2021
Changed `appServiceLinuxContainer` schema object to support optional inbound private endpoint.

**Example**
```json
"appServiceLinuxContainer": {
"value": {
"enablePrivateEndpoint": true
}
}
```

### December 30, 2021

Changed `aks` schema object to support optional deployment of AKS using the `enabled` key as a required field.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,24 @@ module privatezone_datalake_file '../../../../azresources/network/private-dns-zo
}
}

module privatezone_as '../../../../azresources/network/private-dns-zone.bicep' = {
name: 'deploy-privatezone-as'
scope: resourceGroup()
params: {
zone: 'privatelink.azurewebsites.net'
vnetId: vnet.id

dnsCreateNewZone: true
dnsLinkToVirtualNetwork: true
dnsExistingZoneSubscriptionId: ''
dnsExistingZoneResourceGroupName: ''
registrationEnabled: false
}
}


output privateEndpointSubnetId string = '${vnet.id}/subnets/pe'
output appServiceSubnetId string = '${vnet.id}/subnets/appService'
output dataLakeBlobPrivateDnsZoneId string = privatezone_datalake_blob.outputs.privateDnsZoneId
output dataLakeFilePrivateDnsZoneId string = privatezone_datalake_file.outputs.privateDnsZoneId
output asPrivateDnsZoneId string = privatezone_as.outputs.privateDnsZoneId
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
targetScope = 'subscription'

resource rgCompute 'Microsoft.Resources/resourceGroups@2020-06-01' existing = {
name: 'testasp234'
name: 'testpeenablednot'
}

module appInsights '../../../../azresources/monitor/ai-web.bicep' = {
Expand Down Expand Up @@ -68,6 +68,9 @@ module appService '../../../../azresources/compute/web/appservice-linux-containe
storageId: dataLakeMetaData.outputs.storageId

vnetIntegrationSubnetId: networking.outputs.appServiceSubnetId
enablePrivateEndpoint: false
privateEndpointSubnetId: networking.outputs.privateEndpointSubnetId
privateZoneId: networking.outputs.asPrivateDnsZoneId
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ module test '../../../../landingzones/lz-machinelearning/main.bicep' = {
enabled: true
skuName: 'P1V2'
skuTier: 'Premium'
enablePrivateEndpoint: true
}

hubNetwork: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ az webapp config appsettings set --resource-group <rg> --name <unique-app-servic
az webapp config set --resource-group <rg> --name <unique-app-service-name> --linux-fx-version 'DOCKER|<container-registry-name>.azurecr.io/test_image:<date_time_tag>'
az resource update --resource-group <rg> --name <unique-app-service-name>/config/web --set properties.acrUseManagedIdentityCreds=true --resource-type 'Microsoft.Web/sites/config'

# can redeploy app service if anything issues come up
az webapp create --resource-group <rg> --plan <app-service-plan> --name <unique-app-service-name> --deployment-container-image-name 'DOCKER|<docker-address>'
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
3 changes: 2 additions & 1 deletion tests/schemas/lz-machinelearning/AKS-AzureCNI-Calico.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
3 changes: 2 additions & 1 deletion tests/schemas/lz-machinelearning/AKS-Kubenet-Calico.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
3 changes: 2 additions & 1 deletion tests/schemas/lz-machinelearning/AKSIsFalse.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@
"value": {
"enabled": true,
"skuName": "P1V2",
"skuTier": "Premium"
"skuTier": "Premium",
"enablePrivateEndpoint": true
}
},
"sqldb": {
Expand Down
Loading