Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
63 changes: 36 additions & 27 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ resource resourceGroupTags 'Microsoft.Resources/tags@2025-04-01' = {
}
}

// ========== AVM Telemetry ========== //
// This is a standard Azure Verified Modules (AVM) pattern for collecting anonymous usage telemetry.
// It deploys a no-op nested deployment that tracks module usage without collecting any customer data.
// For more information, see https://aka.ms/avm/TelemetryInfo
#disable-next-line no-deployments-resources
resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) {
name: '46d3xbcp.ptn.sa-convknowledgemining.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}'
Expand Down Expand Up @@ -336,7 +340,11 @@ module virtualNetwork 'modules/virtualNetwork.bicep' = if (enablePrivateNetworki
enableTelemetry: enableTelemetry
}
}
// Azure Bastion Host

// ========== Azure Bastion Host ========== //
// Bastion Host provides secure RDP/SSH connectivity to VMs without exposing them via public IP addresses.
// This is deployed when enablePrivateNetworking=true for WAF compliance and operational access to the jumpbox VM.
// Purpose: Secure administrative access to private networking resources for troubleshooting and maintenance.
var bastionHostName = 'bas-${solutionSuffix}'
module bastionHost 'br/public:avm/res/network/bastion-host:0.8.2' = if (enablePrivateNetworking) {
name: take('avm.res.network.bastion-host.${bastionHostName}', 64)
Expand Down Expand Up @@ -365,7 +373,12 @@ module bastionHost 'br/public:avm/res/network/bastion-host:0.8.2' = if (enablePr
}
}

// Jumpbox Virtual Machine
// ========== Jumpbox Virtual Machine ========== //
// Jumpbox VM serves as a secure access point for managing resources in a private virtual network.
// This is deployed when enablePrivateNetworking=true for WAF compliance.
// Purpose: Provides administrative access to private endpoints, AI services, and other resources
// that are not accessible from the public internet. Accessed via Azure Bastion for enhanced security.
// Configuration: vmAdminUsername, vmAdminPassword, and vmSize parameters control the VM setup.
var jumpboxVmName = take('vm-jumpbox-${solutionSuffix}', 15)
module jumpboxVM 'br/public:avm/res/compute/virtual-machine:0.21.0' = if (enablePrivateNetworking) {
name: take('avm.res.compute.virtual-machine.${jumpboxVmName}', 64)
Expand Down Expand Up @@ -509,8 +522,7 @@ module backendUserAssignedIdentity 'br/public:avm/res/managed-identity/user-assi
// ========== AI Foundry: AI Services ========== //
// WAF best practices for Open AI: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-openai

var existingOpenAIEndpoint = !empty(existingAiFoundryAiProjectResourceId) ? format('https://{0}.openai.azure.com/', split(existingAiFoundryAiProjectResourceId, '/')[8]) : ''
var existingProjEndpoint = !empty(existingAiFoundryAiProjectResourceId) ? format('https://{0}.services.ai.azure.com/api/projects/{1}', split(existingAiFoundryAiProjectResourceId, '/')[8], split(existingAiFoundryAiProjectResourceId, '/')[10]) : ''
var existingProjEndpoint= !empty(existingAiFoundryAiProjectResourceId) ? format('https://{0}.services.ai.azure.com/api/projects/{1}', split(existingAiFoundryAiProjectResourceId, '/')[8], split(existingAiFoundryAiProjectResourceId, '/')[10]) : ''
var existingAIServicesName = !empty(existingAiFoundryAiProjectResourceId) ? split(existingAiFoundryAiProjectResourceId, '/')[8] : ''
var existingAIProjectName = !empty(existingAiFoundryAiProjectResourceId) ? split(existingAiFoundryAiProjectResourceId, '/')[10] : ''

Expand All @@ -528,10 +540,7 @@ var aiFoundryAiProjectResourceName = useExistingAiFoundryAiProject
? split(existingAiFoundryAiProjectResourceId, '/')[10]
: 'proj-${solutionSuffix}'

// NOTE: Required version 'Microsoft.CognitiveServices/accounts@2024-04-01-preview' not available in AVM
// var aiFoundryAiServicesResourceName = 'aif-${solutionSuffix}'
var aiFoundryAiServicesAiProjectResourceName = 'proj-${solutionSuffix}'
var aiFoundryAIservicesEnabled = true
var aiModelDeployments = [
{
name: gptModelName
Expand Down Expand Up @@ -567,7 +576,7 @@ resource existingAiFoundryAiServicesProject 'Microsoft.CognitiveServices/account
parent: existingAiFoundryAiServices
}

module aiFoundryAiServices 'modules/ai-services.bicep' = if (aiFoundryAIservicesEnabled) {
module aiFoundryAiServices 'modules/ai-services.bicep' = {
name: take('avm.res.cognitive-services.account.${aiFoundryAiServicesResourceName}', 64)
params: {
name: aiFoundryAiServicesResourceName
Expand All @@ -580,9 +589,7 @@ module aiFoundryAiServices 'modules/ai-services.bicep' = if (aiFoundryAIservices
kind: 'AIServices'
disableLocalAuth: true
customSubDomainName: aiFoundryAiServicesResourceName
apiProperties: {
//staticsEnabled: false
}
apiProperties: {}
networkAcls: {
defaultAction: 'Allow'
virtualNetworkRules: []
Expand Down Expand Up @@ -759,22 +766,24 @@ module searchServiceUpdate 'br/public:avm/res/search/search-service:0.12.0' = {
semanticSearch: 'free'
// Use the deployment tags provided to the template
tags: tags
publicNetworkAccess: 'Enabled' //enablePrivateNetworking ? 'Disabled' : 'Enabled'
privateEndpoints: false //enablePrivateNetworking
? [
{
name: 'pep-${aiSearchName}'
customNetworkInterfaceName: 'nic-${aiSearchName}'
privateDnsZoneGroup: {
privateDnsZoneGroupConfigs: [
{ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.search]!.outputs.resourceId }
]
// Respect the deployment-wide private networking setting for Search as well.
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
privateEndpoints: enablePrivateNetworking
? [
Comment thread
Kanchan-Microsoft marked this conversation as resolved.
{
name: 'pep-search-${solutionSuffix}'
subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
privateDnsZoneGroup: {
Comment on lines +769 to +776
privateDnsZoneGroupConfigs: [
{
name: 'search-dns-zone-group'
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.search]!.outputs.resourceId
}
]
}
}
service: 'searchService'
subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
}
]
: []
]
: []
}
dependsOn: [
searchService
Expand Down Expand Up @@ -1148,7 +1157,7 @@ module webServerFarm 'br/public:avm/res/web/serverfarm:0.5.0' = {
diagnosticSettings: enableMonitoring ? [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }] : null
// WAF aligned configuration for Scalability
skuName: enableScalability || enableRedundancy ? 'P1v3' : 'B3'
skuCapacity: enableScalability ? 1 : 1
skuCapacity: 1
// WAF aligned configuration for Redundancy
zoneRedundant: enableRedundancy ? true : false
}
Expand Down
Loading
Loading