@@ -124,7 +124,7 @@ param enableRedundancy bool = false
124124param enablePrivateNetworking bool = false
125125
126126@description ('Optional. The Container Registry hostname where the docker images are located.' )
127- param acrName string = 'byocgacontainerreg' // testapwaf
127+ param acrName string = 'byocgacontainerreg'
128128
129129@description ('Optional. Image Tag.' )
130130param imageTag string = 'latest_waf_2025-09-18_736'
@@ -138,7 +138,6 @@ param enablePurgeProtection bool = false
138138@description ('Optional created by user name' )
139139param createdBy string = contains (deployer (), 'userPrincipalName' )? split (deployer ().userPrincipalName , '@' )[0 ]: deployer ().objectId
140140
141-
142141// ============== //
143142// Variables //
144143// ============== //
@@ -369,17 +368,107 @@ module userAssignedIdentity 'br/public:avm/res/managed-identity/user-assigned-id
369368 }
370369}
371370
372- // ========== Network Module ========== //
373- module network 'modules/network.bicep' = if (enablePrivateNetworking ) {
374- name : take ('module.network.${solutionSuffix }' , 64 )
371+ // ========== Virtual Network and Networking Components ========== //
372+
373+ // Virtual Network with NSGs and Subnets
374+ module virtualNetwork 'modules/virtualNetwork.bicep' = if (enablePrivateNetworking ) {
375+ name : take ('module.virtualNetwork.${solutionSuffix }' , 64 )
376+ params : {
377+ name : 'vnet-${solutionSuffix }'
378+ addressPrefixes : ['10.0.0.0/20' ] // 4096 addresses (enough for 8 /23 subnets or 16 /24)
379+ location : solutionLocation
380+ tags : tags
381+ logAnalyticsWorkspaceId : logAnalyticsWorkspaceResourceId
382+ resourceSuffix : solutionSuffix
383+ enableTelemetry : enableTelemetry
384+ }
385+ }
386+
387+ // Azure Bastion Host
388+ var bastionHostName = 'bas-${solutionSuffix }'
389+ module bastionHost 'br/public:avm/res/network/bastion-host:0.6.1' = if (enablePrivateNetworking ) {
390+ name : take ('avm.res.network.bastion-host.${bastionHostName }' , 64 )
391+ params : {
392+ name : bastionHostName
393+ skuName : 'Standard'
394+ location : solutionLocation
395+ virtualNetworkResourceId : virtualNetwork !.outputs .resourceId
396+ diagnosticSettings : [
397+ {
398+ name : 'bastionDiagnostics'
399+ workspaceResourceId : logAnalyticsWorkspaceResourceId
400+ logCategoriesAndGroups : [
401+ {
402+ categoryGroup : 'allLogs'
403+ enabled : true
404+ }
405+ ]
406+ }
407+ ]
408+ tags : tags
409+ enableTelemetry : enableTelemetry
410+ publicIPAddressObject : {
411+ name : 'pip-${bastionHostName }'
412+ zones : []
413+ }
414+ }
415+ }
416+
417+ // Jumpbox Virtual Machine
418+ var jumpboxVmName = take ('vm-jumpbox-${solutionSuffix }' , 15 )
419+ module jumpboxVM 'br/public:avm/res/compute/virtual-machine:0.15.0' = if (enablePrivateNetworking ) {
420+ name : take ('avm.res.compute.virtual-machine.${jumpboxVmName }' , 64 )
375421 params : {
376- resourcesName : solutionSuffix
377- logAnalyticsWorkSpaceResourceId : logAnalyticsWorkspaceResourceId
378- vmAdminUsername : vmAdminUsername ?? 'JumpboxAdminUser'
379- vmAdminPassword : vmAdminPassword ?? 'JumpboxAdminP@ssw0rd1234!'
380- vmSize : vmSize ?? 'Standard_DS2_v2' // Default VM size
422+ name : take (jumpboxVmName , 15 ) // Shorten VM name to 15 characters to avoid Azure limits
423+ vmSize : vmSize ?? 'Standard_DS2_v2'
381424 location : solutionLocation
425+ adminUsername : vmAdminUsername ?? 'JumpboxAdminUser'
426+ adminPassword : vmAdminPassword ?? 'JumpboxAdminP@ssw0rd1234!'
382427 tags : tags
428+ zone : 0
429+ imageReference : {
430+ offer : 'WindowsServer'
431+ publisher : 'MicrosoftWindowsServer'
432+ sku : '2019-datacenter'
433+ version : 'latest'
434+ }
435+ osType : 'Windows'
436+ osDisk : {
437+ name : 'osdisk-${jumpboxVmName }'
438+ managedDisk : {
439+ storageAccountType : 'Standard_LRS'
440+ }
441+ }
442+ encryptionAtHost : false // Some Azure subscriptions do not support encryption at host
443+ nicConfigurations : [
444+ {
445+ name : 'nic-${jumpboxVmName }'
446+ ipConfigurations : [
447+ {
448+ name : 'ipconfig1'
449+ subnetResourceId : virtualNetwork !.outputs .jumpboxSubnetResourceId
450+ }
451+ ]
452+ diagnosticSettings : [
453+ {
454+ name : 'jumpboxDiagnostics'
455+ workspaceResourceId : logAnalyticsWorkspaceResourceId
456+ logCategoriesAndGroups : [
457+ {
458+ categoryGroup : 'allLogs'
459+ enabled : true
460+ }
461+ ]
462+ metricCategories : [
463+ {
464+ category : 'AllMetrics'
465+ enabled : true
466+ }
467+ ]
468+ }
469+ ]
470+ }
471+ ]
383472 enableTelemetry : enableTelemetry
384473 }
385474}
@@ -425,8 +514,8 @@ module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.7.1' = [
425514 enableTelemetry : enableTelemetry
426515 virtualNetworkLinks : [
427516 {
428- name : take ('vnetlink-${network !.outputs .vnetName }-${split (zone , '.' )[1 ]}' , 80 )
429- virtualNetworkResourceId : network !.outputs .vnetResourceId
517+ name : take ('vnetlink-${virtualNetwork !.outputs .name }-${split (zone , '.' )[1 ]}' , 80 )
518+ virtualNetworkResourceId : virtualNetwork !.outputs .resourceId
430519 }
431520 ]
432521 }
@@ -479,6 +568,48 @@ module existingAiFoundryAiServicesDeployments 'modules/ai-services-deployments.b
479568 }
480569}
481570
571+ // ========== Private Endpoint for Existing AI Services ========== //
572+ // var shouldCreatePrivateEndpoint = useExistingAiFoundryAiProject && enablePrivateNetworking
573+ // module existingAiServicesPrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.11.0' = if (shouldCreatePrivateEndpoint) {
574+ // name: take('module.private-endpoint.${existingAiFoundryAiServices.name}', 64)
575+ // params: {
576+ // name: 'pep-${existingAiFoundryAiServices.name}'
577+ // location: location
578+ // subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
579+ // customNetworkInterfaceName: 'nic-${existingAiFoundryAiServices.name}'
580+ // privateDnsZoneGroup: {
581+ // privateDnsZoneGroupConfigs: [
582+ // {
583+ // name: 'ai-services-dns-zone-cognitiveservices'
584+ // privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
585+ // }
586+ // {
587+ // name: 'ai-services-dns-zone-openai'
588+ // privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.openAI]!.outputs.resourceId
589+ // }
590+ // {
591+ // name: 'ai-services-dns-zone-aiservices'
592+ // privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
593+ // }
594+ // ]
595+ // }
596+ // privateLinkServiceConnections: [
597+ // {
598+ // name: 'pep-${existingAiFoundryAiServices.name}'
599+ // properties: {
600+ // groupIds: ['account']
601+ // privateLinkServiceId: existingAiFoundryAiServices.id
602+ // }
603+ // }
604+ // ]
605+ // tags: tags
606+ // }
607+ // dependsOn: [
608+ // existingAiFoundryAiServices
609+ // avmPrivateDnsZones
610+ // ]
611+ // }
612+
482613module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-services/account:0.13.2' = if (!useExistingAiFoundryAiProject ) {
483614 name : take ('avm.res.cognitive-services.account.${aiFoundryAiServicesResourceName }' , 64 )
484615 params : {
@@ -539,7 +670,7 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
539670 {
540671 name : 'pep-${aiFoundryAiServicesResourceName }'
541672 customNetworkInterfaceName : 'nic-${aiFoundryAiServicesResourceName }'
542- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
673+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
543674 privateDnsZoneGroup : {
544675 privateDnsZoneGroupConfigs : [
545676 {
@@ -584,7 +715,7 @@ module aiFoundryAiServicesProject 'modules/ai-project.bicep' = if (!useExistingA
584715}
585716
586717var aiFoundryAiProjectEndpoint = useExistingAiFoundryAiProject
587- ? existingAiFoundryAiServicesProject !. properties . endpoints [ 'AI Foundry API' ]
718+ ? 'https://${ aiFoundryAiServicesResourceName }.services.ai.azure.com/api/projects/${ aiFoundryAiProjectResourceName }'
588719 : aiFoundryAiServicesProject !.outputs .apiEndpoint
589720
590721// ========== Search Service to AI Services Role Assignment ========== //
@@ -666,7 +797,7 @@ module aiSearch 'br/public:avm/res/search/search-service:0.11.1' = {
666797 { privateDnsZoneResourceId : avmPrivateDnsZones [dnsZoneIndex .searchService ]!.outputs .resourceId }
667798 ]
668799 }
669- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
800+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
670801 service : 'searchService'
671802 }
672803 ]
@@ -756,7 +887,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
756887 }
757888 ]
758889 }
759- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
890+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
760891 service : 'blob'
761892 }
762893 {
@@ -769,7 +900,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
769900 }
770901 ]
771902 }
772- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
903+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
773904 service : 'queue'
774905 }
775906 ]
@@ -833,7 +964,7 @@ module cosmosDB 'br/public:avm/res/document-db/database-account:0.15.0' = {
833964 ]
834965 }
835966 service : 'Sql'
836- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
967+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
837968 }
838969 ]
839970 : []
@@ -899,7 +1030,7 @@ module keyvault 'br/public:avm/res/key-vault/vault:0.12.1' = {
8991030 ]
9001031 }
9011032 service : 'vault'
902- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
1033+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
9031034 }
9041035 ]
9051036 : []
@@ -1086,7 +1217,7 @@ module webSite 'modules/web-sites.bicep' = {
10861217 // WAF aligned configuration for Private Networking
10871218 vnetRouteAllEnabled : enablePrivateNetworking ? true : false
10881219 vnetImagePullEnabled : enablePrivateNetworking ? true : false
1089- virtualNetworkSubnetId : enablePrivateNetworking ? network !.outputs .subnetWebResourceId : null
1220+ virtualNetworkSubnetId : enablePrivateNetworking ? virtualNetwork !.outputs .webSubnetResourceId : null
10901221 publicNetworkAccess : 'Enabled'
10911222 }
10921223}
0 commit comments