Skip to content

Commit 3facc1a

Browse files
adde ampls
1 parent 0e28812 commit 3facc1a

1 file changed

Lines changed: 117 additions & 10 deletions

File tree

infra/main.bicep

Lines changed: 117 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,25 @@ module applicationInsights 'br/public:avm/res/insights/component:0.7.0' = if (en
291291
retentionInDays: 365
292292
kind: 'web'
293293
disableIpMasking: false
294-
disableLocalAuth: true
295294
flowType: 'Bluefield'
295+
// WAF aligned configuration for Private Networking - block public ingestion/query
296+
publicNetworkAccessForIngestion: enablePrivateNetworking ? 'Disabled' : 'Enabled'
297+
publicNetworkAccessForQuery: enablePrivateNetworking ? 'Disabled' : 'Enabled'
298+
}
299+
}
300+
301+
// ========== Data Collection Endpoint (DCE) ========== //
302+
// Required for Azure Monitor Private Link - provides private ingestion and configuration endpoints
303+
// Per: https://learn.microsoft.com/en-us/azure/azure-monitor/fundamentals/private-link-configure
304+
module dataCollectionEndpoint 'br/public:avm/res/insights/data-collection-endpoint:0.5.0' = if (enablePrivateNetworking && enableMonitoring) {
305+
name: take('avm.res.insights.data-collection-endpoint.${solutionSuffix}', 64)
306+
params: {
307+
name: 'dce-${solutionSuffix}'
308+
location: location
309+
kind: 'Windows'
310+
publicNetworkAccess: 'Disabled'
311+
tags: allTags
312+
enableTelemetry: enableTelemetry
296313
}
297314
}
298315

@@ -320,6 +337,10 @@ var privateDnsZones = [
320337
'privatelink.vaultcore.azure.net'
321338
'privatelink.blob.${environment().suffixes.storage}'
322339
'privatelink.file.${environment().suffixes.storage}'
340+
'privatelink.monitor.azure.com' // Azure Monitor global endpoints (App Insights, DCE)
341+
'privatelink.oms.opinsights.azure.com' // Log Analytics OMS endpoints
342+
'privatelink.ods.opinsights.azure.com' // Log Analytics ODS ingestion endpoints
343+
'privatelink.agentsvc.azure-automation.net' // Agent service automation endpoints
323344
]
324345

325346
// DNS Zone Index Constants
@@ -331,6 +352,10 @@ var dnsZoneIndex = {
331352
keyVault: 4
332353
storageBlob: 5
333354
storageFile: 6
355+
monitor: 7
356+
oms: 8
357+
ods: 9
358+
agentSvc: 10
334359
}
335360

336361
// ===================================================
@@ -356,6 +381,76 @@ module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.8.0' = [
356381
}
357382
]
358383

384+
// ========== Azure Monitor Private Link Scope (AMPLS) ========== //
385+
// Step 1: Create AMPLS
386+
// Step 2: Connect Azure Monitor resources (LAW, Application Insights, DCE) to the AMPLS
387+
// Step 3: Connect AMPLS to a private endpoint with required DNS zones
388+
// Per: https://learn.microsoft.com/en-us/azure/azure-monitor/fundamentals/private-link-configure
389+
module azureMonitorPrivateLinkScope 'br/public:avm/res/insights/private-link-scope:0.6.0' = if (enablePrivateNetworking) {
390+
name: take('avm.res.insights.private-link-scope.${solutionSuffix}', 64)
391+
#disable-next-line no-unnecessary-dependson
392+
dependsOn: [logAnalyticsWorkspace, applicationInsights, dataCollectionEndpoint, virtualNetwork]
393+
params: {
394+
name: 'ampls-${solutionSuffix}'
395+
location: 'global'
396+
// Access mode: PrivateOnly ensures all ingestion and queries go through private link
397+
accessModeSettings: {
398+
ingestionAccessMode: 'PrivateOnly'
399+
queryAccessMode: 'PrivateOnly'
400+
}
401+
// Step 2: Connect Azure Monitor resources to the AMPLS as scoped resources
402+
scopedResources: concat([
403+
{
404+
name: 'scoped-law'
405+
linkedResourceId: logAnalyticsWorkspaceResourceId
406+
}
407+
], enableMonitoring ? [
408+
{
409+
name: 'scoped-appi'
410+
linkedResourceId: applicationInsights!.outputs.resourceId
411+
}
412+
{
413+
name: 'scoped-dce'
414+
linkedResourceId: dataCollectionEndpoint!.outputs.resourceId
415+
}
416+
] : [])
417+
// Step 3: Connect AMPLS to a private endpoint
418+
// The private endpoint requires 5 DNS zones per documentation:
419+
// - privatelink.monitor.azure.com (App Insights + DCE global endpoints)
420+
// - privatelink.oms.opinsights.azure.com (Log Analytics OMS)
421+
// - privatelink.ods.opinsights.azure.com (Log Analytics ODS ingestion)
422+
// - privatelink.agentsvc.azure-automation.net (Agent service automation)
423+
// - privatelink.blob.core.windows.net (Agent solution packs storage)
424+
privateEndpoints: [
425+
{
426+
name: 'pep-ampls-${solutionSuffix}'
427+
subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
428+
privateDnsZoneGroup: {
429+
privateDnsZoneGroupConfigs: [
430+
{
431+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.monitor]!.outputs.resourceId
432+
}
433+
{
434+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.oms]!.outputs.resourceId
435+
}
436+
{
437+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.ods]!.outputs.resourceId
438+
}
439+
{
440+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.agentSvc]!.outputs.resourceId
441+
}
442+
{
443+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.storageBlob]!.outputs.resourceId
444+
}
445+
]
446+
}
447+
}
448+
]
449+
tags: allTags
450+
enableTelemetry: enableTelemetry
451+
}
452+
}
453+
359454
// Azure Bastion Host
360455
var bastionHostName = 'bas-${solutionSuffix}'
361456
module bastionHost 'br/public:avm/res/network/bastion-host:0.8.0' = if (enablePrivateNetworking) {
@@ -437,6 +532,7 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-
437532
location: dataCollectionRulesLocation
438533
dataCollectionRuleProperties: {
439534
kind: 'Windows'
535+
dataCollectionEndpointResourceId: dataCollectionEndpoint!.outputs.resourceId
440536
dataSources: {
441537
performanceCounters: [
442538
{
@@ -501,19 +597,20 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-
501597
streams: [
502598
'Microsoft-WindowsEvent'
503599
]
504-
eventLogName: 'Security'
505-
eventTypes: [
506-
{
507-
eventType: 'Audit Success'
508-
}
509-
{
510-
eventType: 'Audit Failure'
511-
}
512-
]
513600
xPathQueries: [
514601
'Security!*[System[(EventID=4624 or EventID=4625)]]'
515602
]
516603
}
604+
{
605+
name: 'AppAndSystemEvents'
606+
streams: [
607+
'Microsoft-WindowsEvent'
608+
]
609+
xPathQueries: [
610+
'Application!*[System[(Level=1 or Level=2 or Level=3)]]'
611+
'System!*[System[(Level=1 or Level=2 or Level=3)]]'
612+
]
613+
}
517614
]
518615
}
519616
destinations: {
@@ -535,6 +632,16 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-
535632
transformKql: 'source'
536633
outputStream: 'Microsoft-Perf'
537634
}
635+
{
636+
streams: [
637+
'Microsoft-WindowsEvent'
638+
]
639+
destinations: [
640+
'la-${dataCollectionRulesResourceName}'
641+
]
642+
transformKql: 'source'
643+
outputStream: 'Microsoft-WindowsEvent'
644+
}
538645
]
539646
}
540647
}

0 commit comments

Comments
 (0)