From 0c3a7261909d5c594b4c8428f7f7229852d76517 Mon Sep 17 00:00:00 2001 From: Josh Bradley Date: Wed, 12 Jun 2024 00:40:58 -0400 Subject: [PATCH] cleanup deployment code (#5) --- infra/abbreviations.json | 3 +- infra/core/ai-search/ai-search.bicep | 9 +- infra/core/aks/aks.bicep | 95 ++++++++++++---- infra/core/apim/apim.bicep | 6 +- ...icep => apim.graphrag-documentation.bicep} | 0 .../core/apim/apim.graphrag-servicedef.bicep | 2 +- infra/core/blob/storage.bicep | 1 + infra/core/cosmosdb/cosmosdb.bicep | 8 +- infra/core/log-analytics/log.bicep | 2 + infra/core/monitor/private-link-scope.bicep | 28 +++++ .../vnet/batch-private-dns-vnet-link.bicep | 14 +++ infra/core/vnet/private-dns-vnet-link.bicep | 23 ++++ infra/core/vnet/private-dns-zone-groups.json | 18 ++++ infra/core/vnet/private-endpoint.bicep | 41 +++++++ .../vnet/privatelink-private-dns-zones.bicep | 84 +++++++++++++++ infra/core/vnet/vnet-dns-link.bicep | 21 ++++ infra/deploy.sh | 21 +++- infra/helm/graphrag/values.yaml | 8 +- infra/main.bicep | 101 +++++++++++++++++- 19 files changed, 437 insertions(+), 48 deletions(-) rename infra/core/apim/{apim.docs-servicedef.bicep => apim.graphrag-documentation.bicep} (100%) create mode 100644 infra/core/monitor/private-link-scope.bicep create mode 100644 infra/core/vnet/batch-private-dns-vnet-link.bicep create mode 100644 infra/core/vnet/private-dns-vnet-link.bicep create mode 100644 infra/core/vnet/private-dns-zone-groups.json create mode 100644 infra/core/vnet/private-endpoint.bicep create mode 100644 infra/core/vnet/privatelink-private-dns-zones.bicep create mode 100644 infra/core/vnet/vnet-dns-link.bicep diff --git a/infra/abbreviations.json b/infra/abbreviations.json index aba7c094..ac1f5ad8 100644 --- a/infra/abbreviations.json +++ b/infra/abbreviations.json @@ -104,6 +104,7 @@ "operationalInsightsWorkspaces": "log-", "portalDashboards": "dash-", "powerBIDedicatedCapacities": "pbi-", + "privateEndpoint": "pep-", "purviewAccounts": "pview-", "recoveryServicesVaults": "rsv-", "resourcesResourceGroups": "rg-", @@ -133,4 +134,4 @@ "webSitesAppServiceEnvironment": "ase-", "webSitesFunctions": "func-", "webStaticSites": "stapp-" -} +} \ No newline at end of file diff --git a/infra/core/ai-search/ai-search.bicep b/infra/core/ai-search/ai-search.bicep index b514f70b..443fecc7 100644 --- a/infra/core/ai-search/ai-search.bicep +++ b/infra/core/ai-search/ai-search.bicep @@ -17,14 +17,10 @@ resource aiSearch 'Microsoft.Search/searchServices@2024-03-01-preview' = { name: 'standard' } properties: { - authOptions: { - aadOrApiKey: { - aadAuthFailureMode: 'http401WithBearerChallenge' - } - } + disableLocalAuth: true replicaCount: 1 partitionCount: 1 - publicNetworkAccess: 'Enabled' + publicNetworkAccess: 'disabled' semanticSearch: 'disabled' } } @@ -37,4 +33,5 @@ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ } ] +output id string = aiSearch.id output name string = aiSearch.name diff --git a/infra/core/aks/aks.bicep b/infra/core/aks/aks.bicep index 65061817..718a43f9 100644 --- a/infra/core/aks/aks.bicep +++ b/infra/core/aks/aks.bicep @@ -13,7 +13,7 @@ param logAnalyticsWorkspaceId string @description('The auto-upgrade profile.') param autoUpgradeProfile object = { nodeOsUpgradeChannel: 'NodeImage' - upgradeChannel: 'patch' + upgradeChannel: 'node-image' } @description('Optional DNS prefix to use with hosted Kubernetes API server FQDN.') @@ -27,7 +27,7 @@ param systemOsDiskSizeGB int = 128 @description('The number of nodes for the system node pool.') @minValue(1) @maxValue(50) -param systemNodeCount int = 3 +param systemNodeCount int = 1 @description('The size of the system Virtual Machine.') param systemVMSize string = 'standard_d4s_v5' @@ -73,34 +73,25 @@ resource aks 'Microsoft.ContainerService/managedClusters@2023-10-01' = { agentPoolProfiles: [ { name: 'agentpool' - osDiskSizeGB: systemOsDiskSizeGB - count: systemNodeCount - vmSize: systemVMSize - osType: 'Linux' - mode: 'System' - enableEncryptionAtHost: enableEncryptionAtHost - vnetSubnetID: vnetSubnetIdVar - } - { - name: 'graphrag' enableAutoScaling: true + upgradeSettings: { + maxSurge: '50%' + } minCount: 1 maxCount: 10 osDiskSizeGB: systemOsDiskSizeGB - count: graphragNodeCount - vmSize: graphragVMSize + count: systemNodeCount + vmSize: systemVMSize osType: 'Linux' - mode: 'User' + mode: 'System' enableEncryptionAtHost: enableEncryptionAtHost vnetSubnetID: vnetSubnetIdVar - nodeLabels: { - workload: 'graphrag' - } - tags: { - workload: 'graphrag' - } + type: 'VirtualMachineScaleSets' } ] + autoScalerProfile: { + expander: 'least-waste' + } linuxProfile: { adminUsername: linuxAdminUsername ssh: { @@ -125,6 +116,68 @@ resource aks 'Microsoft.ContainerService/managedClusters@2023-10-01' = { } } } + + resource graphragNodePool 'agentPools@2024-02-01' = { + name: 'graphrag' + properties: { + enableAutoScaling: true + upgradeSettings: { + maxSurge: '50%' + } + minCount: 1 + maxCount: 10 + osDiskSizeGB: systemOsDiskSizeGB + count: graphragNodeCount + vmSize: graphragVMSize + osType: 'Linux' + mode: 'User' + enableEncryptionAtHost: enableEncryptionAtHost + vnetSubnetID: vnetSubnetIdVar + nodeLabels: { + workload: 'graphrag' + } + tags: { + workload: 'graphrag' + } + type: 'VirtualMachineScaleSets' + } + } +} + +resource aksManagedAutoUpgradeSchedule 'Microsoft.ContainerService/managedClusters/maintenanceConfigurations@2024-03-02-preview' = { + parent: aks + name: 'aksManagedAutoUpgradeSchedule' + properties: { + maintenanceWindow: { + schedule: { + weekly: { + intervalWeeks: 1 + dayOfWeek: 'Sunday' + } + } + durationHours: 4 + startDate: '2024-06-11' + startTime: '12:00' + } + } +} + +resource aksManagedNodeOSUpgradeSchedule 'Microsoft.ContainerService/managedClusters/maintenanceConfigurations@2024-03-02-preview' = { + parent: aks + name: 'aksManagedNodeOSUpgradeSchedule' + properties: { + maintenanceWindow: { + schedule: { + weekly: { + intervalWeeks: 1 + dayOfWeek: 'Saturday' + } + } + durationHours: 4 + startDate: '2024-06-11' + startTime: '12:00' + } + } } output name string = aks.name diff --git a/infra/core/apim/apim.bicep b/infra/core/apim/apim.bicep index 23898847..d556a6a6 100644 --- a/infra/core/apim/apim.bicep +++ b/infra/core/apim/apim.bicep @@ -440,15 +440,19 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { location: location kind: 'web' properties: { - Application_Type:'web' + Application_Type: 'web' WorkspaceResourceId: logAnalyticsWorkspaceId + publicNetworkAccessForIngestion: 'Disabled' + publicNetworkAccessForQuery: 'Enabled' } } output apimIPs array = apiManagementService.properties.publicIPAddresses output apimGatewayUrl string = apiManagementService.properties.gatewayUrl output appInsightsName string = appInsights.name +output appInsightsId string = appInsights.id output name string = apiManagementService.name output vnetName string = virtualNetwork.name output vnetId string = virtualNetwork.id +output defaultSubnetId string = virtualNetwork.properties.subnets[0].id output hostnameConfigs array = apiManagementService.properties.hostnameConfigurations diff --git a/infra/core/apim/apim.docs-servicedef.bicep b/infra/core/apim/apim.graphrag-documentation.bicep similarity index 100% rename from infra/core/apim/apim.docs-servicedef.bicep rename to infra/core/apim/apim.graphrag-documentation.bicep diff --git a/infra/core/apim/apim.graphrag-servicedef.bicep b/infra/core/apim/apim.graphrag-servicedef.bicep index 45ebb684..5f8de8b0 100644 --- a/infra/core/apim/apim.graphrag-servicedef.bicep +++ b/infra/core/apim/apim.graphrag-servicedef.bicep @@ -8,7 +8,7 @@ param apimname string resource api 'Microsoft.ApiManagement/service/apis@2023-03-01-preview' = { name: '${apimname}/${name}' properties: { - displayName: 'Graph RAG' + displayName: 'GraphRAG' apiRevision: '1' subscriptionRequired: true serviceUrl: backendUrl diff --git a/infra/core/blob/storage.bicep b/infra/core/blob/storage.bicep index 751a6267..e929c112 100644 --- a/infra/core/blob/storage.bicep +++ b/infra/core/blob/storage.bicep @@ -69,5 +69,6 @@ resource roleAssignmentResources 'Microsoft.Authorization/roleAssignments@2022-0 } ] +output id string = storage.id output name string = storage.name output primaryEndpoints object = storage.properties.primaryEndpoints diff --git a/infra/core/cosmosdb/cosmosdb.bicep b/infra/core/cosmosdb/cosmosdb.bicep index 11a0035d..364612cf 100644 --- a/infra/core/cosmosdb/cosmosdb.bicep +++ b/infra/core/cosmosdb/cosmosdb.bicep @@ -25,7 +25,7 @@ resource cosmosDb 'Microsoft.DocumentDB/databaseAccounts@2022-11-15' = { type: 'SystemAssigned' } properties: { - publicNetworkAccess: 'Enabled' + publicNetworkAccess: 'Disabled' enableAutomaticFailover: false enableMultipleWriteLocations: false isVirtualNetworkFilterEnabled: false @@ -206,8 +206,6 @@ resource cosmosDbIdentityAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRo } } - -output cosmosDbResourceId string = cosmosDb.id -output cosmosDbResourceName string = cosmosDb.name -output serviceName string = cosmosDb.name +output id string = cosmosDb.id +output name string = cosmosDb.name output endpoint string = cosmosDb.properties.documentEndpoint diff --git a/infra/core/log-analytics/log.bicep b/infra/core/log-analytics/log.bicep index 6f092086..4e0a7449 100644 --- a/infra/core/log-analytics/log.bicep +++ b/infra/core/log-analytics/log.bicep @@ -12,6 +12,8 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10 location: location properties: { retentionInDays: 30 + publicNetworkAccessForIngestion: 'Disabled' + publicNetworkAccessForQuery: 'Enabled' features: { immediatePurgeDataOn30Days: true } diff --git a/infra/core/monitor/private-link-scope.bicep b/infra/core/monitor/private-link-scope.bicep new file mode 100644 index 00000000..e839b81e --- /dev/null +++ b/infra/core/monitor/private-link-scope.bicep @@ -0,0 +1,28 @@ +param privateLinkScopeName string +param privateLinkScopedResources array = [] + +param queryAccessMode string = 'Open' +param ingestionAccessMode string = 'PrivateOnly' + +resource privateLinkScope 'microsoft.insights/privateLinkScopes@2021-07-01-preview' = { + name: privateLinkScopeName + location: 'global' + properties: { + accessModeSettings: { + queryAccessMode: queryAccessMode + ingestionAccessMode: ingestionAccessMode + } + } +} + +resource scopedResources 'microsoft.insights/privateLinkScopes/scopedResources@2021-07-01-preview' = [ + for id in privateLinkScopedResources: { + name: uniqueString(id) + parent: privateLinkScope + properties: { + linkedResourceId: id + } + } +] + +output privateLinkScopeId string = privateLinkScope.id diff --git a/infra/core/vnet/batch-private-dns-vnet-link.bicep b/infra/core/vnet/batch-private-dns-vnet-link.bicep new file mode 100644 index 00000000..9155c47c --- /dev/null +++ b/infra/core/vnet/batch-private-dns-vnet-link.bicep @@ -0,0 +1,14 @@ +@description('The name of the private DNS zone.') +param privateDnsZoneNames array + +param vnetResourceIds array + +module privateDnsVnetLinks 'private-dns-vnet-link.bicep' = [ + for (privateDnsZoneName, i) in privateDnsZoneNames: { + name: '${privateDnsZoneName}-vnet-link-${i}' + params: { + privateDnsZoneName: privateDnsZoneName + vnetResourceIds: vnetResourceIds + } + } +] diff --git a/infra/core/vnet/private-dns-vnet-link.bicep b/infra/core/vnet/private-dns-vnet-link.bicep new file mode 100644 index 00000000..e1c601c6 --- /dev/null +++ b/infra/core/vnet/private-dns-vnet-link.bicep @@ -0,0 +1,23 @@ +param privateDnsZoneName string + +param vnetResourceIds array + +resource dnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: privateDnsZoneName + location: 'global' + properties: {} +} + +resource dnsZoneLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = [ + for vnetId in vnetResourceIds: { + name: uniqueString(vnetId) + location: 'global' + parent: dnsZone + properties: { + registrationEnabled: false + virtualNetwork: { + id: vnetId + } + } + } +] diff --git a/infra/core/vnet/private-dns-zone-groups.json b/infra/core/vnet/private-dns-zone-groups.json new file mode 100644 index 00000000..02c531bf --- /dev/null +++ b/infra/core/vnet/private-dns-zone-groups.json @@ -0,0 +1,18 @@ +{ + "azureCloud": { + "azureMonitor": [ + "privatelink.monitor.azure.com", + "privatelink.oms.opinsights.azure.com", + "privatelink.agentsvc.azure-automation.net", + "privatelink.ods.opinsights.azure.com" + ] + }, + "azureusgovernment": { + "azureMonitor": [ + "privatelink.monitor.azure.us", + "privatelink.oms.opinsights.azure.us", + "privatelink.agentsvc.azure-automation.us", + "privatelink.ods.opinsights.azure.us" + ] + } +} \ No newline at end of file diff --git a/infra/core/vnet/private-endpoint.bicep b/infra/core/vnet/private-endpoint.bicep new file mode 100644 index 00000000..4bd72a7d --- /dev/null +++ b/infra/core/vnet/private-endpoint.bicep @@ -0,0 +1,41 @@ +@description('Resource ID of service the private endpoint is for') +param privateLinkServiceId string + +param privateEndpointName string + +@description('The resource ID of the subnet to deploy the private endpoint to') +param subnetId string + +param groupId string + +param location string = resourceGroup().location + +@description('map of group id to array of private dns zone configs to associate with the private endpoint') +param privateDnsZoneConfigs array + +resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-05-01' = { + name: privateEndpointName + location: location + properties: { + privateLinkServiceConnections: [ + { + name: privateEndpointName + properties: { + privateLinkServiceId: privateLinkServiceId + groupIds: [groupId] + } + } + ] + subnet: { + id: subnetId + } + } +} + +resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2021-05-01' = { + name: groupId + parent: privateEndpoint + properties: { + privateDnsZoneConfigs: privateDnsZoneConfigs + } +} diff --git a/infra/core/vnet/privatelink-private-dns-zones.bicep b/infra/core/vnet/privatelink-private-dns-zones.bicep new file mode 100644 index 00000000..89c92c96 --- /dev/null +++ b/infra/core/vnet/privatelink-private-dns-zones.bicep @@ -0,0 +1,84 @@ +var aiSearchPrivateDnsZoneName = 'privatelink.search.windows.net' +var blobStoragePrivateDnsZoneName = 'privatelink.blob.${environment().suffixes.storage}' +var queueStoragePrivateDnsZoneName = 'privatelink.queue.${environment().suffixes.storage}' +var cosmosDbPrivateDnsZoneName = 'privatelink.documents.azure.com' +var storagePrivateDnsZoneNames = [blobStoragePrivateDnsZoneName, queueStoragePrivateDnsZoneName] + +var cloudName = toLower(environment().name) +var privateDnsZoneData = loadJsonContent('private-dns-zone-groups.json') + +var azureMonitorPrivateDnsZones = privateDnsZoneData[cloudName].azureMonitor + +var privateDnsZones = union(azureMonitorPrivateDnsZones, storagePrivateDnsZoneNames, [cosmosDbPrivateDnsZoneName], [aiSearchPrivateDnsZoneName]) + +@description('Virtual Network IDs to link to') +param linkedVnetResourceIds array + +resource privateDnsZoneResources 'Microsoft.Network/privateDnsZones@2020-06-01' = [ + for name in privateDnsZones: { + name: name + location: 'global' + } +] + +module dnsVnetLinks 'vnet-dns-link.bicep' = [ + for (privateDnsZoneName, index) in privateDnsZones: { + name: replace(privateDnsZoneName, '.', '-') + params: { + privateDnsZoneName: privateDnsZoneResources[index].name + vnetResourceIds: linkedVnetResourceIds + } + } +] + +output azureMonitorPrivateDnsZoneConfigs array = [ + for zoneName in union(azureMonitorPrivateDnsZones, [blobStoragePrivateDnsZoneName]): { + name: privateDnsZoneResources[indexOf(privateDnsZones, zoneName)].name + properties: { + #disable-next-line use-resource-id-functions + privateDnsZoneId: privateDnsZoneResources[indexOf(privateDnsZones, zoneName)].id + } + } +] + +output blobStoragePrivateDnsZoneConfigs array = [ + { + name: blobStoragePrivateDnsZoneName + properties: { + #disable-next-line use-resource-id-functions + privateDnsZoneId: privateDnsZoneResources[indexOf(privateDnsZones, blobStoragePrivateDnsZoneName)].id + } + } +] + +output queueStoragePrivateDnsZoneConfigs array = [ + { + name: queueStoragePrivateDnsZoneName + properties: { + #disable-next-line use-resource-id-functions + privateDnsZoneId: privateDnsZoneResources[indexOf(privateDnsZones, queueStoragePrivateDnsZoneName)].id + } + } +] + +output cosmosDbPrivateDnsZoneConfigs array = [ + { + name: privateDnsZoneResources[indexOf(privateDnsZones, cosmosDbPrivateDnsZoneName)].name + properties: { + #disable-next-line use-resource-id-functions + privateDnsZoneId: privateDnsZoneResources[indexOf(privateDnsZones, cosmosDbPrivateDnsZoneName)].id + } + } +] + +output aiSearchPrivateDnsZoneConfigs array = [ + { + name: privateDnsZoneResources[indexOf(privateDnsZones, aiSearchPrivateDnsZoneName)].name + properties: { + #disable-next-line use-resource-id-functions + privateDnsZoneId: privateDnsZoneResources[indexOf(privateDnsZones, aiSearchPrivateDnsZoneName)].id + } + } +] + +output privateDnsZones array = privateDnsZones diff --git a/infra/core/vnet/vnet-dns-link.bicep b/infra/core/vnet/vnet-dns-link.bicep new file mode 100644 index 00000000..85c011c6 --- /dev/null +++ b/infra/core/vnet/vnet-dns-link.bicep @@ -0,0 +1,21 @@ +param privateDnsZoneName string + +param vnetResourceIds array + +resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = { + name: privateDnsZoneName +} + +resource dnsVnetLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = [ + for vnetId in vnetResourceIds: { + name: '${replace(privateDnsZoneName, '.', '-')}-${uniqueString(vnetId)}' + parent: privateDnsZone + location: 'global' + properties: { + virtualNetwork: { + id: vnetId + } + registrationEnabled: false + } + } +] diff --git a/infra/deploy.sh b/infra/deploy.sh index 1f4d400a..ba19fc90 100755 --- a/infra/deploy.sh +++ b/infra/deploy.sh @@ -283,8 +283,20 @@ peerVirtualNetworks () { echo "...peering complete" } -deployGraphrag () { - printf "Deploying graphrag... " +linkPrivateDnsToAks () { + echo "Linking private DNS zone to AKS..." + local privateDnsZoneNames=$(jq -r .azure_private_dns_zones.value <<< $AZURE_OUTPUTS) + exitIfValueEmpty "$privateDnsZoneNames" "Unable to parse private DNS zone names from deployment outputs, exiting..." + AZURE_DEPLOY_RESULTS=$(az deployment group create --name "private-dns-to-aks" --no-prompt -o json --template-file ./core/vnet/batch-private-dns-vnet-link.bicep \ + -g $RESOURCE_GROUP \ + --parameters "vnetResourceIds=[\"$AKS_VNET_ID\"]" \ + --parameters "privateDnsZoneNames=$privateDnsZoneNames") + exitIfCommandFailed $? "Error linking private DNS to AKS vnet..." + echo "...linking private DNS complete" +} + +deployHelmChart () { + printf "Deploying graphrag helm chart... " local workloadId=$(jq -r .azure_workload_identity_client_id.value <<< $AZURE_OUTPUTS) exitIfValueEmpty "$workloadId" "Unable to parse workload id from Azure outputs, exiting..." @@ -350,7 +362,7 @@ deployGraphrag () { local helmResult=$? "$reset_x" && set +x - exitIfCommandFailed $helmResult "Error deploying helm charts, exiting..." + exitIfCommandFailed $helmResult "Error deploying helm chart, exiting..." } waitForGraphragExternalIp () { @@ -468,8 +480,9 @@ assignAKSPullRoleToRegistry $RESOURCE_GROUP $AKS_NAME $CONTAINER_REGISTRY_SERVER # Deploy kubernetes resources setupAksCredentials $RESOURCE_GROUP $AKS_NAME populateAksVnetInfo $RESOURCE_GROUP $AKS_NAME +linkPrivateDnsToAks peerVirtualNetworks -deployGraphrag +deployHelmChart deployGraphragDnsRecord # Import GraphRAG API into APIM diff --git a/infra/helm/graphrag/values.yaml b/infra/helm/graphrag/values.yaml index 69c7265e..f4d7e38d 100644 --- a/infra/helm/graphrag/values.yaml +++ b/infra/helm/graphrag/values.yaml @@ -94,8 +94,8 @@ query: enabled: true minReplicas: 1 maxReplicas: 20 - targetCPUUtilizationPercentage: 50 - # targetMemoryUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 50 + # targetCPUUtilizationPercentage: 50 # Additional volumes on the output Deployment definition. volumes: [] @@ -179,8 +179,8 @@ index: enabled: true minReplicas: 1 maxReplicas: 20 - targetCPUUtilizationPercentage: 50 - # targetMemoryUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 50 + # targetCPUUtilizationPercentage: 50 # Additional volumes on the output Deployment definition. volumes: [] diff --git a/infra/main.bicep b/infra/main.bicep index 44aa043c..7e5ce274 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -17,7 +17,7 @@ var resourceBaseNameFinal = !empty(resourceBaseName) ? resourceBaseName : toLowe @minLength(1) @maxLength(64) -@description('Name of the graphrag instance to be created.') +@description('Name of the resource group that GraphRAG will be deployed in.') param graphRagName string @description('Location for all resources') @@ -157,7 +157,7 @@ module storage 'core/blob/storage.bicep' = { roleDefinitionId: roles.storageQueueDataContributor } ] - publicNetworkAccess: 'Enabled' + publicNetworkAccess: 'Disabled' deleteRetentionPolicy: { enabled: true days: 5 @@ -185,7 +185,7 @@ module apim 'core/apim/apim.bicep' = { } } -module updateapimservice 'core/apim/apim.docs-servicedef.bicep' = { +module graphragApi 'core/apim/apim.graphrag-documentation.bicep' = { name: 'apimservice' scope: rg params: { @@ -221,6 +221,93 @@ module privateDnsZone 'core/vnet/private-dns-zone.bicep' = { } } +module privatelinkPrivateDns 'core/vnet/privatelink-private-dns-zones.bicep' = { + name: 'privatelink-private-dns-zones' + scope: rg + params: { + linkedVnetResourceIds: [ + apim.outputs.vnetId + ] + } +} + +module azureMonitorPrivateLinkScope 'core/monitor/private-link-scope.bicep' = { + name: 'azureMonitorPrivateLinkScope' + scope: rg + params: { + privateLinkScopeName: 'pls-${resourceBaseNameFinal}' + privateLinkScopedResources: [ + log.outputs.id + apim.outputs.appInsightsId + ] + } +} + +module cosmosDbPrivateEndpoint 'core/vnet/private-endpoint.bicep' = { + name: 'cosmosDbPrivateEndpoint' + scope: rg + params: { + privateEndpointName: '${abbrs.privateEndpoint}cosmos-${cosmosdb.outputs.name}' + location: location + privateLinkServiceId: cosmosdb.outputs.id + subnetId: apim.outputs.defaultSubnetId + groupId: 'Sql' + privateDnsZoneConfigs: privatelinkPrivateDns.outputs.cosmosDbPrivateDnsZoneConfigs + } +} + +module blobStoragePrivateEndpoint 'core/vnet/private-endpoint.bicep' = { + name: 'blobStoragePrivateEndpoint' + scope: rg + params: { + privateEndpointName: '${abbrs.privateEndpoint}blob-${storage.outputs.name}' + location: location + privateLinkServiceId: storage.outputs.id + subnetId: apim.outputs.defaultSubnetId + groupId: 'blob' + privateDnsZoneConfigs: privatelinkPrivateDns.outputs.blobStoragePrivateDnsZoneConfigs + } +} + +module queueStoragePrivateEndpoint 'core/vnet/private-endpoint.bicep' = { + name: 'queueStoragePrivateEndpoint' + scope: rg + params: { + privateEndpointName: '${abbrs.privateEndpoint}queue-${storage.outputs.name}' + location: location + privateLinkServiceId: storage.outputs.id + subnetId: apim.outputs.defaultSubnetId + groupId: 'queue' + privateDnsZoneConfigs: privatelinkPrivateDns.outputs.queueStoragePrivateDnsZoneConfigs + } +} + +module aiSearchPrivateEndpoint 'core/vnet/private-endpoint.bicep' = { + name: 'aiSearchPrivateEndpoint' + scope: rg + params: { + privateEndpointName: '${abbrs.privateEndpoint}search-${aiSearch.outputs.name}' + location: location + privateLinkServiceId: aiSearch.outputs.id + subnetId: apim.outputs.defaultSubnetId + groupId: 'searchService' + privateDnsZoneConfigs: privatelinkPrivateDns.outputs.aiSearchPrivateDnsZoneConfigs + } +} + +module privateLinkScopePrivateEndpoint 'core/vnet/private-endpoint.bicep' = { + name: 'privateLinkScopePrivateEndpoint' + scope: rg + params: { + privateEndpointName: '${abbrs.privateEndpoint}pls-${resourceBaseNameFinal}' + location: location + privateLinkServiceId: azureMonitorPrivateLinkScope.outputs.privateLinkScopeId + subnetId: apim.outputs.defaultSubnetId + groupId: 'azuremonitor' + privateDnsZoneConfigs: privatelinkPrivateDns.outputs.azureMonitorPrivateDnsZoneConfigs + } +} + output azure_location string = location output azure_tenant_id string = tenant().tenantId output azure_ai_search_name string = aiSearch.outputs.name @@ -231,8 +318,8 @@ output azure_aks_service_account_name string = aksServiceAccountName output azure_storage_account string = storage.outputs.name output azure_storage_account_blob_url string = storage.outputs.primaryEndpoints.blob output azure_cosmosdb_endpoint string = cosmosdb.outputs.endpoint -output azure_cosmosdb_name string = cosmosdb.outputs.cosmosDbResourceName -output azure_cosmosdb_id string = cosmosdb.outputs.cosmosDbResourceId +output azure_cosmosdb_name string = cosmosdb.outputs.name +output azure_cosmosdb_id string = cosmosdb.outputs.id output azure_apim_name string = apim.outputs.name output azure_apim_url string = apim.outputs.apimGatewayUrl output azure_apim_vnet_name string = apim.outputs.vnetName @@ -243,3 +330,7 @@ output azure_graphrag_url string = graphRagUrl output azure_workload_identity_client_id string = workloadIdentity.outputs.client_id output azure_workload_identity_principal_id string = workloadIdentity.outputs.principal_id output azure_workload_identity_name string = workloadIdentity.outputs.name +output azure_private_dns_zones array = union( + privatelinkPrivateDns.outputs.privateDnsZones, + [privateDnsZone.outputs.dns_zone_name] +)