@@ -288,9 +288,9 @@ param newGuidString string = newGuid()
288288
289289@description ('Optional. Principal object for user or service principal to assign application roles. Format: {"id":"<object-id>", "name":"<name-or-upn>", "type":"User|Group|ServicePrincipal"}' )
290290param principal object = {
291- id : '' // Principal ID
292- name : '' // Principal name
293- type : 'User' // Principal type ('User', 'Group', or 'ServicePrincipal')
291+ id : '' // Principal ID
292+ name : '' // Principal name
293+ type : 'User' // Principal type ('User', 'Group', or 'ServicePrincipal')
294294}
295295
296296@description ('Optional. Application Environment.' )
@@ -451,21 +451,165 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT
451451 }
452452}
453453
454- var networkResourceName = take ('network-${solutionSuffix }' , 25 ) // limit to 25 chars
455- module network 'modules/network.bicep' = if (enablePrivateNetworking ) {
456- name : take ('network-${solutionSuffix }-deployment' , 64 )
454+ // var networkResourceName = take('network-${solutionSuffix}', 25) // limit to 25 chars
455+ // module network 'modules/network.bicep' = if (enablePrivateNetworking) {
456+ // name: take('network-${solutionSuffix}-deployment', 64)
457+ // params: {
458+ // resourcesName: networkResourceName
459+ // logAnalyticsWorkSpaceResourceId: enableMonitoring ? monitoring!.outputs.logAnalyticsWorkspaceId : ''
460+ // vmAdminUsername: empty(virtualMachineAdminUsername) ? 'JumpboxAdminUser' : virtualMachineAdminUsername
461+ // vmAdminPassword: empty(virtualMachineAdminPassword) ? 'JumpboxAdminP@ssw0rd1234!' : virtualMachineAdminPassword
462+ // vmSize: empty(vmSize) ? 'Standard_DS2_v2' : vmSize
463+ // location: location
464+ // tags: allTags
465+ // enableTelemetry: enableTelemetry
466+ // }
467+ // }
468+
469+ // Virtual Network with NSGs and Subnets
470+ module virtualNetwork 'modules/virtualNetwork.bicep' = if (enablePrivateNetworking ) {
471+ name : take ('module.virtualNetwork.${solutionSuffix }' , 64 )
457472 params : {
458- resourcesName : networkResourceName
459- logAnalyticsWorkSpaceResourceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : ''
460- vmAdminUsername : empty (virtualMachineAdminUsername ) ? 'JumpboxAdminUser' : virtualMachineAdminUsername
461- vmAdminPassword : empty (virtualMachineAdminPassword ) ? 'JumpboxAdminP@ssw0rd1234!' : virtualMachineAdminPassword
462- vmSize : empty (vmSize ) ? 'Standard_DS2_v2' : vmSize
473+ name : 'vnet-${solutionSuffix }'
474+ addressPrefixes : ['10.0.0.0/20' ] // 4096 addresses (enough for 8 /23 subnets or 16 /24)
463475 location : location
464- tags : allTags
476+ tags : tags
477+ logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : ''
478+ resourceSuffix : solutionSuffix
479+ enableTelemetry : enableTelemetry
480+ }
481+ }
482+
483+ // Azure Bastion Host
484+ var bastionHostName = 'bas-${solutionSuffix }'
485+ module bastionHost 'br/public:avm/res/network/bastion-host:0.6.1' = if (enablePrivateNetworking ) {
486+ name : take ('avm.res.network.bastion-host.${bastionHostName }' , 64 )
487+ params : {
488+ name : bastionHostName
489+ skuName : 'Standard'
490+ location : location
491+ virtualNetworkResourceId : virtualNetwork !.outputs .resourceId
492+ diagnosticSettings : [
493+ {
494+ name : 'bastionDiagnostics'
495+ workspaceResourceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : ''
496+ logCategoriesAndGroups : [
497+ {
498+ categoryGroup : 'allLogs'
499+ enabled : true
500+ }
501+ ]
502+ }
503+ ]
504+ tags : tags
505+ enableTelemetry : enableTelemetry
506+ publicIPAddressObject : {
507+ name : 'pip-${bastionHostName }'
508+ zones : []
509+ }
510+ }
511+ }
512+
513+ // Jumpbox Virtual Machine
514+ var jumpboxVmName = take ('vm-jumpbox-${solutionSuffix }' , 15 )
515+ module jumpboxVM 'br/public:avm/res/compute/virtual-machine:0.15.0' = if (enablePrivateNetworking ) {
516+ name : take ('avm.res.compute.virtual-machine.${jumpboxVmName }' , 64 )
517+ params : {
518+ name : take (jumpboxVmName , 15 ) // Shorten VM name to 15 characters to avoid Azure limits
519+ vmSize : vmSize ?? 'Standard_DS2_v2'
520+ location : location
521+ adminUsername : !empty (virtualMachineAdminUsername ) ? virtualMachineAdminUsername : 'JumpboxAdminUser'
522+ adminPassword : !empty (virtualMachineAdminPassword ) ? virtualMachineAdminPassword : 'JumpboxAdminP@ssw0rd1234!'
523+ tags : tags
524+ zone : 0
525+ imageReference : {
526+ offer : 'WindowsServer'
527+ publisher : 'MicrosoftWindowsServer'
528+ sku : '2019-datacenter'
529+ version : 'latest'
530+ }
531+ osType : 'Windows'
532+ osDisk : {
533+ name : 'osdisk-${jumpboxVmName }'
534+ managedDisk : {
535+ storageAccountType : 'Standard_LRS'
536+ }
537+ }
538+ encryptionAtHost : false // Some Azure subscriptions do not support encryption at host
539+ nicConfigurations : [
540+ {
541+ name : 'nic-${jumpboxVmName }'
542+ ipConfigurations : [
543+ {
544+ name : 'ipconfig1'
545+ subnetResourceId : virtualNetwork !.outputs .jumpboxSubnetResourceId
546+ }
547+ ]
548+ diagnosticSettings : [
549+ {
550+ name : 'jumpboxDiagnostics'
551+ workspaceResourceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : ''
552+ logCategoriesAndGroups : [
553+ {
554+ categoryGroup : 'allLogs'
555+ enabled : true
556+ }
557+ ]
558+ metricCategories : [
559+ {
560+ category : 'AllMetrics'
561+ enabled : true
562+ }
563+ ]
564+ }
565+ ]
566+ }
567+ ]
465568 enableTelemetry : enableTelemetry
466569 }
467570}
468571
572+ // Create Maintenance Configuration for VM
573+ // Required for PSRule.Rules.Azure compliance: Azure.VM.MaintenanceConfig
574+ // using AVM Virtual Machine module
575+ // https://github.com/Azure/bicep-registry-modules/tree/main/avm/res/compute/virtual-machine
576+
577+ module maintenanceConfiguration 'br/public:avm/res/maintenance/maintenance-configuration:0.3.1' = {
578+ name : take ('avm.res.maintenance.maintenance-configuration.${jumpboxVmName }' , 64 )
579+ params : {
580+ name : 'mc-${jumpboxVmName }'
581+ location : location
582+ tags : tags
583+ enableTelemetry : enableTelemetry
584+ extensionProperties : {
585+ InGuestPatchMode : 'User'
586+ }
587+ maintenanceScope : 'InGuestPatch'
588+ maintenanceWindow : {
589+ startDateTime : '2024-06-16 00:00'
590+ duration : '03:55'
591+ timeZone : 'W. Europe Standard Time'
592+ recurEvery : '1Day'
593+ }
594+ visibility : 'Custom'
595+ installPatches : {
596+ rebootSetting : 'IfRequired'
597+ windowsParameters : {
598+ classificationsToInclude : [
599+ 'Critical'
600+ 'Security'
601+ ]
602+ }
603+ linuxParameters : {
604+ classificationsToInclude : [
605+ 'Critical'
606+ 'Security'
607+ ]
608+ }
609+ }
610+ }
611+ }
612+
469613// ========== Managed Identity ========== //
470614var userAssignedIdentityResourceName = 'id-${solutionSuffix }'
471615module managedIdentityModule 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.1' = {
@@ -521,8 +665,8 @@ module avmPrivateDnsZones './modules/private-dns-zone/private-dns-zone.bicep' =
521665 enableTelemetry : enableTelemetry
522666 virtualNetworkLinks : [
523667 {
524- name : take ('vnetlink-${network !.outputs .vnetName }-${split (zone , '.' )[1 ]}' , 80 )
525- virtualNetworkResourceId : network !.outputs .vnetResourceId
668+ name : take ('vnetlink-${virtualNetwork !.outputs .name }-${split (zone , '.' )[1 ]}' , 80 )
669+ virtualNetworkResourceId : virtualNetwork !.outputs .resourceId
526670 }
527671 ]
528672 }
@@ -583,7 +727,7 @@ module cosmosDBModule './modules/document-db/database-account/database-account.b
583727 ]
584728 }
585729 service : 'Sql'
586- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
730+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
587731 }
588732 ]
589733 : []
@@ -648,7 +792,7 @@ module postgresDBModule 'br/public:avm/res/db-for-postgre-sql/flexible-server:0.
648792 ]
649793 }
650794 service : 'postgresqlServer'
651- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
795+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
652796 }
653797 ]
654798 : []
@@ -759,7 +903,7 @@ module keyvault './modules/key-vault/vault/vault.bicep' = {
759903 ]
760904 }
761905 service : 'vault'
762- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
906+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
763907 }
764908 ]
765909 : []
@@ -861,7 +1005,7 @@ module openai 'modules/core/ai/cognitiveservices.bicep' = {
8611005 enablePrivateNetworking : enablePrivateNetworking
8621006 enableMonitoring : enableMonitoring
8631007 enableTelemetry : enableTelemetry
864- subnetResourceId : enablePrivateNetworking ? network !.outputs .subnetPrivateEndpointsResourceId : null
1008+ subnetResourceId : enablePrivateNetworking ? virtualNetwork !.outputs .pepsSubnetResourceId : null
8651009
8661010 logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : null
8671011
@@ -910,7 +1054,7 @@ module computerVision 'modules/core/ai/cognitiveservices.bicep' = if (useAdvance
9101054 enablePrivateNetworking : enablePrivateNetworking
9111055 enableMonitoring : enableMonitoring
9121056 enableTelemetry : enableTelemetry
913- subnetResourceId : enablePrivateNetworking ? network !.outputs .subnetPrivateEndpointsResourceId : null
1057+ subnetResourceId : enablePrivateNetworking ? virtualNetwork !.outputs .pepsSubnetResourceId : null
9141058
9151059 logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : null
9161060 userAssignedResourceId : managedIdentityModule .outputs .resourceId
@@ -953,7 +1097,7 @@ module speechService 'modules/core/ai/cognitiveservices.bicep' = {
9531097 enablePrivateNetworking : enablePrivateNetworkingSpeech
9541098 enableMonitoring : enableMonitoring
9551099 enableTelemetry : enableTelemetry
956- subnetResourceId : enablePrivateNetworkingSpeech ? network !.outputs .subnetPrivateEndpointsResourceId : null
1100+ subnetResourceId : enablePrivateNetworkingSpeech ? virtualNetwork !.outputs .pepsSubnetResourceId : null
9571101
9581102 logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : null
9591103 disableLocalAuth : false
@@ -1024,7 +1168,7 @@ module search 'br/public:avm/res/search/search-service:0.11.1' = if (databaseTyp
10241168 }
10251169 ]
10261170 }
1027- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
1171+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
10281172 service : 'searchService'
10291173 }
10301174 ]
@@ -1116,7 +1260,7 @@ module web 'modules/app/web.bicep' = {
11161260 diagnosticSettings : enableMonitoring ? [{ workspaceResourceId : monitoring !.outputs .logAnalyticsWorkspaceId }] : []
11171261 vnetRouteAllEnabled : enablePrivateNetworking ? true : false
11181262 vnetImagePullEnabled : enablePrivateNetworking ? true : false
1119- virtualNetworkSubnetId : enablePrivateNetworking ? network !.outputs .subnetWebResourceId : ''
1263+ virtualNetworkSubnetId : enablePrivateNetworking ? virtualNetwork !.outputs .webSubnetResourceId : ''
11201264 publicNetworkAccess : 'Enabled' // Always enabling public network access
11211265 applicationInsightsName : enableMonitoring ? monitoring !.outputs .applicationInsightsName : ''
11221266 appSettings : union (
@@ -1295,7 +1439,7 @@ module adminweb 'modules/app/adminweb.bicep' = {
12951439 diagnosticSettings : enableMonitoring ? [{ workspaceResourceId : monitoring !.outputs .logAnalyticsWorkspaceId }] : []
12961440 vnetImagePullEnabled : enablePrivateNetworking ? true : false
12971441 vnetRouteAllEnabled : enablePrivateNetworking ? true : false
1298- virtualNetworkSubnetId : enablePrivateNetworking ? network !.outputs .subnetWebResourceId : ''
1442+ virtualNetworkSubnetId : enablePrivateNetworking ? virtualNetwork !.outputs .webSubnetResourceId : ''
12991443 publicNetworkAccess : 'Enabled' // Always enabling public network access
13001444 }
13011445}
@@ -1318,7 +1462,7 @@ module function 'modules/app/function.bicep' = {
13181462 userAssignedIdentityClientId : managedIdentityModule .outputs .clientId
13191463 // WAF aligned configurations
13201464 diagnosticSettings : enableMonitoring ? [{ workspaceResourceId : monitoring !.outputs .logAnalyticsWorkspaceId }] : []
1321- virtualNetworkSubnetId : enablePrivateNetworking ? network !.outputs .subnetWebResourceId : ''
1465+ virtualNetworkSubnetId : enablePrivateNetworking ? virtualNetwork !.outputs .webSubnetResourceId : ''
13221466 vnetRouteAllEnabled : enablePrivateNetworking ? true : false
13231467 vnetImagePullEnabled : enablePrivateNetworking ? true : false
13241468 publicNetworkAccess : 'Enabled' // Always enabling public network access
@@ -1415,7 +1559,7 @@ module formrecognizer 'modules/core/ai/cognitiveservices.bicep' = {
14151559 enablePrivateNetworking : enablePrivateNetworking
14161560 enableMonitoring : enableMonitoring
14171561 enableTelemetry : enableTelemetry
1418- subnetResourceId : enablePrivateNetworking ? network !.outputs .subnetPrivateEndpointsResourceId : null
1562+ subnetResourceId : enablePrivateNetworking ? virtualNetwork !.outputs .pepsSubnetResourceId : null
14191563
14201564 logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : null
14211565 userAssignedResourceId : managedIdentityModule .outputs .resourceId
@@ -1466,7 +1610,7 @@ module contentsafety 'modules/core/ai/cognitiveservices.bicep' = {
14661610 enablePrivateNetworking : enablePrivateNetworking
14671611 enableMonitoring : enableMonitoring
14681612 enableTelemetry : enableTelemetry
1469- subnetResourceId : enablePrivateNetworking ? network !.outputs .subnetPrivateEndpointsResourceId : null
1613+ subnetResourceId : enablePrivateNetworking ? virtualNetwork !.outputs .pepsSubnetResourceId : null
14701614
14711615 logAnalyticsWorkspaceId : enableMonitoring ? monitoring !.outputs .logAnalyticsWorkspaceId : null
14721616 userAssignedResourceId : managedIdentityModule .outputs .resourceId
@@ -1564,7 +1708,7 @@ module storage './modules/storage/storage-account/storage-account.bicep' = {
15641708 }
15651709 ]
15661710 }
1567- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
1711+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
15681712 service : 'blob'
15691713 }
15701714 {
@@ -1577,7 +1721,7 @@ module storage './modules/storage/storage-account/storage-account.bicep' = {
15771721 }
15781722 ]
15791723 }
1580- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
1724+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
15811725 service : 'queue'
15821726 }
15831727 {
@@ -1590,7 +1734,7 @@ module storage './modules/storage/storage-account/storage-account.bicep' = {
15901734 }
15911735 ]
15921736 }
1593- subnetResourceId : network !.outputs .subnetPrivateEndpointsResourceId
1737+ subnetResourceId : virtualNetwork !.outputs .pepsSubnetResourceId
15941738 service : 'file'
15951739 }
15961740 ]
@@ -1736,7 +1880,7 @@ module createIndex 'br/public:avm/res/resources/deployment-script:0.5.1' = if (d
17361880 storageAccountResourceId : storage .outputs .resourceId
17371881 subnetResourceIds : enablePrivateNetworking
17381882 ? [
1739- network !.outputs .subnetDeploymentScriptsResourceId
1883+ virtualNetwork !.outputs .deploymentScriptsSubnetResourceId
17401884 ]
17411885 : null
17421886 tags : tags
@@ -1834,7 +1978,9 @@ var azureContentSafetyInfo = string({
18341978 endpoint : contentsafety .outputs .endpoint
18351979})
18361980
1837- var backendUrl = hostingModel == 'container' ? 'https://${functionName }-docker.azurewebsites.net' : 'https://${functionName }.azurewebsites.net'
1981+ var backendUrl = hostingModel == 'container'
1982+ ? 'https://${functionName }-docker.azurewebsites.net'
1983+ : 'https://${functionName }.azurewebsites.net'
18381984
18391985@description ('Connection string for the Application Insights instance.' )
18401986output APPLICATIONINSIGHTS_CONNECTION_STRING string = enableMonitoring
0 commit comments