From 6fac970ebc41490ac036834acb51ba465ee8e4a7 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 7 Jan 2025 12:47:05 -0800 Subject: [PATCH 1/4] Configure Azure Developer Pipeline From b16fd31ad48af8644f67c46863056ffbb0520783 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Tue, 21 Jan 2025 09:31:54 -0800 Subject: [PATCH 2/4] Private endpoints draft --- infra/main.bicep | 11 +++++------ infra/network-isolation.bicep | 37 ++++++++++------------------------- infra/private-endpoints.bicep | 7 ++++--- 3 files changed, 19 insertions(+), 36 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index 5c181cd525..0c86eaf7c0 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -431,7 +431,7 @@ module backend 'core/host/appservice.bicep' = if (deploymentTarget == 'appservic appCommandLine: 'python3 -m gunicorn main:app' scmDoBuildDuringDeployment: true managedIdentity: true - virtualNetworkSubnetId: isolation.outputs.appSubnetId + virtualNetworkSubnetId: usePrivateEndpoint ? isolation.outputs.appSubnetId : '' publicNetworkAccess: publicNetworkAccess allowedOrigins: allowedOrigins clientAppId: clientAppId @@ -472,6 +472,7 @@ module containerApps 'core/host/container-apps.bicep' = if (deploymentTarget == containerAppsEnvironmentName: acaManagedEnvironmentName containerRegistryName: '${containerRegistryName}${resourceToken}' logAnalyticsWorkspaceResourceId: useApplicationInsights ? monitoring.outputs.logAnalyticsWorkspaceId : '' + virtualNetworkSubnetId: usePrivateEndpoint ? isolation.outputs.appSubnetId : '' } } @@ -1047,17 +1048,15 @@ module cosmosDbRoleBackend 'core/security/documentdb-sql-role.bicep' = if (useAu } } -module isolation 'network-isolation.bicep' = { +module isolation 'network-isolation.bicep' = if (usePrivateEndpoint) { name: 'networks' scope: resourceGroup params: { - deploymentTarget: deploymentTarget location: location tags: tags vnetName: '${abbrs.virtualNetworks}${resourceToken}' - // Need to check deploymentTarget due to https://github.com/Azure/bicep/issues/3990 - appServicePlanName: deploymentTarget == 'appservice' ? appServicePlan.outputs.name : '' usePrivateEndpoint: usePrivateEndpoint + containerAppsEnvName: acaManagedEnvironmentName } } @@ -1103,7 +1102,7 @@ var otherPrivateEndpointConnections = (usePrivateEndpoint && deploymentTarget == var privateEndpointConnections = concat(otherPrivateEndpointConnections, openAiPrivateEndpointConnection) -module privateEndpoints 'private-endpoints.bicep' = if (usePrivateEndpoint && deploymentTarget == 'appservice') { +module privateEndpoints 'private-endpoints.bicep' = if (usePrivateEndpoint) { name: 'privateEndpoints' scope: resourceGroup params: { diff --git a/infra/network-isolation.bicep b/infra/network-isolation.bicep index 4dd1e49f86..c623eb7cae 100644 --- a/infra/network-isolation.bicep +++ b/infra/network-isolation.bicep @@ -9,18 +9,15 @@ param location string = resourceGroup().location @description('The tags to apply to all resources') param tags object = {} -@description('The name of an existing App Service Plan to connect to the VNet') -param appServicePlanName string - param usePrivateEndpoint bool = false -@allowed(['appservice', 'containerapps']) -param deploymentTarget string +param containerAppsEnvName string -resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' existing = if (deploymentTarget == 'appservice') { - name: appServicePlanName +resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' existing = { + name: containerAppsEnvName } + module vnet './core/networking/vnet.bicep' = if (usePrivateEndpoint) { name: 'vnet' params: { @@ -36,42 +33,28 @@ module vnet './core/networking/vnet.bicep' = if (usePrivateEndpoint) { privateLinkServiceNetworkPolicies: 'Enabled' } } - { - name: 'AzureBastionSubnet' - properties: { - addressPrefix: '10.0.2.0/24' - privateEndpointNetworkPolicies: 'Enabled' - privateLinkServiceNetworkPolicies: 'Enabled' - } - } - { + { // App Service / Container Apps specific subnet name: 'app-int-subnet' properties: { - addressPrefix: '10.0.3.0/24' + addressPrefix: '10.0.4.0/23' privateEndpointNetworkPolicies: 'Enabled' privateLinkServiceNetworkPolicies: 'Enabled' delegations: [ { - id: appServicePlan.id - name: appServicePlan.name + id: containerAppsEnvironment.id + name: containerAppsEnvironment.name properties: { - serviceName: 'Microsoft.Web/serverFarms' + serviceName: 'Microsoft.App/environments' } } ] } } - { - name: 'vm-subnet' - properties: { - addressPrefix: '10.0.4.0/24' - } - } ] } } -output appSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[2].id : '' +output appSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[1].id : '' output backendSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[0].id : '' output vnetName string = usePrivateEndpoint ? vnet.outputs.name : '' diff --git a/infra/private-endpoints.bicep b/infra/private-endpoints.bicep index 58fe14177e..a26ad08947 100644 --- a/infra/private-endpoints.bicep +++ b/infra/private-endpoints.bicep @@ -81,7 +81,8 @@ module monitorDnsZones './core/networking/private-dns-zones.bicep' = [for monito } }] // Get blob DNS zone index for monitor private link -var dnsZoneBlobIndex = filter(flatten(privateEndpointInfo), info => info.groupId == 'blob')[0].dnsZoneIndex +var blobEndpointInfo = filter(flatten(privateEndpointInfo), info => info.groupId == 'blob') +var dnsZoneBlobIndex = empty(blobEndpointInfo) ? 0 : blobEndpointInfo[0].dnsZoneIndex // Azure Monitor Private Link Scope // https://learn.microsoft.com/azure/azure-monitor/logs/private-link-security @@ -150,9 +151,9 @@ module monitorPrivateEndpoint './core/networking/private-endpoint.bicep' = { } } { - name: dnsZones[dnsZoneBlobIndex].name + name: 'blob-dnszone' // dnsZones[dnsZoneBlobIndex].name properties: { - privateDnsZoneId: dnsZones[dnsZoneBlobIndex].outputs.id + privateDnsZoneId: '/subscriptions/77d8a3d0-8b18-47e9-b773-08bee327bb4a/resourceGroups/rg-pf-ragprivate/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net' // dnsZones[dnsZoneBlobIndex].outputs.id } } ] From 7ad962a7d5698587610addf7890cf8e1be5b8a10 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Mon, 3 Feb 2025 13:59:44 -0800 Subject: [PATCH 3/4] Conditional for SPL --- infra/core/search/search-services.bicep | 1 + infra/main.bicep | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/infra/core/search/search-services.bicep b/infra/core/search/search-services.bicep index 4ee8d6a8fb..fc743758cf 100644 --- a/infra/core/search/search-services.bicep +++ b/infra/core/search/search-services.bicep @@ -55,6 +55,7 @@ resource search 'Microsoft.Search/searchServices@2023-11-01' = { } sku: sku + // https://github.com/Azure/bicep-types-az/issues/2421 resource sharedPrivateLinkResource 'sharedPrivateLinkResources@2023-11-01' = [for (resourceId, i) in sharedPrivateLinkStorageAccounts: { name: 'search-shared-private-link-${i}' properties: { diff --git a/infra/main.bicep b/infra/main.bicep index 0c86eaf7c0..bd6ca4f695 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -701,7 +701,7 @@ module searchService 'core/search/search-services.bicep' = { publicNetworkAccess: publicNetworkAccess == 'Enabled' ? 'enabled' : (publicNetworkAccess == 'Disabled' ? 'disabled' : null) - sharedPrivateLinkStorageAccounts: usePrivateEndpoint ? [storage.outputs.id] : [] + sharedPrivateLinkStorageAccounts: (usePrivateEndpoint && useIntegratedVectorization) ? [storage.outputs.id] : [] } } From 7a82bde8287f12086ced1b0afebe08d479aa8001 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Wed, 5 Feb 2025 16:47:21 -0800 Subject: [PATCH 4/4] private endpoint for ACA --- infra/main.bicep | 10 +++++----- infra/network-isolation.bicep | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index bd6ca4f695..935217b9ec 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -1062,7 +1062,7 @@ module isolation 'network-isolation.bicep' = if (usePrivateEndpoint) { var environmentData = environment() -var openAiPrivateEndpointConnection = (isAzureOpenAiHost && deployAzureOpenAi && deploymentTarget == 'appservice') +var openAiPrivateEndpointConnection = (isAzureOpenAiHost && deployAzureOpenAi) ? [ { groupId: 'account' @@ -1075,7 +1075,7 @@ var openAiPrivateEndpointConnection = (isAzureOpenAiHost && deployAzureOpenAi && } ] : [] -var otherPrivateEndpointConnections = (usePrivateEndpoint && deploymentTarget == 'appservice') +var otherPrivateEndpointConnections = (usePrivateEndpoint) ? [ { groupId: 'blob' @@ -1088,9 +1088,9 @@ var otherPrivateEndpointConnections = (usePrivateEndpoint && deploymentTarget == resourceIds: [searchService.outputs.id] } { - groupId: 'sites' - dnsZoneName: 'privatelink.azurewebsites.net' - resourceIds: [backend.outputs.id] + groupId: 'managedEnvironments' + dnsZoneName: 'privatelink.${location}.azurecontainerapps.io' + resourceIds: [containerApps.outputs.environmentId] } { groupId: 'cosmosdb' diff --git a/infra/network-isolation.bicep b/infra/network-isolation.bicep index c623eb7cae..90e1396453 100644 --- a/infra/network-isolation.bicep +++ b/infra/network-isolation.bicep @@ -57,4 +57,6 @@ module vnet './core/networking/vnet.bicep' = if (usePrivateEndpoint) { output appSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[1].id : '' output backendSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[0].id : '' +output bastionSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[2].id : '' +output vmSubnetId string = usePrivateEndpoint ? vnet.outputs.vnetSubnets[3].id : '' output vnetName string = usePrivateEndpoint ? vnet.outputs.name : ''