|
| 1 | +resources |
| 2 | +| where type == 'microsoft.network/loadbalancers' and sku.name == 'Basic' |
| 3 | +| project fes = properties.frontendIPConfigurations, bes = properties.backendAddressPools,['id'] |
| 4 | +| extend backendPoolCount = array_length(bes) |
| 5 | +| extend internalOrExternal = iff(isnotempty(fes),iff(isnotempty(fes[0].properties.privateIPAddress),'Internal','External'),'None') |
| 6 | + | join kind=leftouter hint.strategy=shuffle ( |
| 7 | + resources |
| 8 | + | where type == 'microsoft.network/publicipaddresses' |
| 9 | + | where properties.publicIPAddressVersion == 'IPv6' |
| 10 | + | extend publicIPv6LBId = tostring(split(properties.ipConfiguration.id,'/frontendIPConfigurations/')[0]) |
| 11 | + | distinct publicIPv6LBId |
| 12 | + ) on $left.id == $right.publicIPv6LBId |
| 13 | + | join kind = leftouter hint.strategy=shuffle ( |
| 14 | + resources |
| 15 | + | where type == 'microsoft.network/networkinterfaces' and isnotempty(properties.virtualMachine.id) |
| 16 | + | extend vmNICHasNSG = isnotnull(properties.networkSecurityGroup.id) |
| 17 | + | extend vmNICSubnetIds = tostring(extract_all('(/subscriptions/[a-f0-9-]+?/resourceGroups/[a-zA-Z0-9-_]+?/providers/Microsoft.Network/virtualNetworks/[a-zA-Z0-9-_]+?/subnets/[a-zA-Z0-9-_]*)',tostring(properties.ipConfigurations))) |
| 18 | + | mv-expand ipConfigs = properties.ipConfigurations |
| 19 | + | extend vmPublicIPId = extract('/subscriptions/[a-f0-9-]+?/resourceGroups/[a-zA-Z0-9-_]+?/providers/Microsoft.Network/publicIPAddresses/[a-zA-Z0-9-_]*',0,tostring(ipConfigs)) |
| 20 | + | where isnotempty(ipConfigs.properties.loadBalancerBackendAddressPools) |
| 21 | + | mv-expand bes = ipConfigs.properties.loadBalancerBackendAddressPools |
| 22 | + | extend nicLoadBalancerId = tostring(split(bes.id,'/backendAddressPools/')[0]) |
| 23 | + | summarize vmNICsNSGStatus = make_set(vmNICHasNSG) by nicLoadBalancerId,vmPublicIPId,vmNICSubnetIds |
| 24 | + | extend allVMNicsHaveNSGs = set_has_element(vmNICsNSGStatus,False) |
| 25 | + | summarize publicIpCount = dcount(vmPublicIPId) by nicLoadBalancerId, allVMNicsHaveNSGs, vmNICSubnetIds |
| 26 | + ) on $left.id == $right.nicLoadBalancerId |
| 27 | + | join kind = leftouter ( |
| 28 | + resources |
| 29 | + | where type == 'microsoft.compute/virtualmachinescalesets' |
| 30 | + | extend vmssSubnetIds = tostring(extract_all('(/subscriptions/[a-f0-9-]+?/resourceGroups/[a-zA-Z0-9-_]+?/providers/Microsoft.Network/virtualNetworks/[a-zA-Z0-9-_]+?/subnets/[a-zA-Z0-9-_]*)',tostring(properties.virtualMachineProfile.networkProfile.networkInterfaceConfigurations))) |
| 31 | + | mv-expand nicConfigs = properties.virtualMachineProfile.networkProfile.networkInterfaceConfigurations |
| 32 | + | extend vmssNicHasNSG = isnotnull(properties.networkSecurityGroup.id) |
| 33 | + | mv-expand ipConfigs = nicConfigs.properties.ipConfigurations |
| 34 | + | extend vmssHasPublicIPConfig = iff(tostring(ipConfigs) matches regex @'publicIPAddressVersion',true,false) |
| 35 | + | where isnotempty(ipConfigs.properties.loadBalancerBackendAddressPools) |
| 36 | + | mv-expand bes = ipConfigs.properties.loadBalancerBackendAddressPools |
| 37 | + | extend vmssLoadBalancerId = tostring(split(bes.id,'/backendAddressPools/')[0]) |
| 38 | + | summarize vmssNICsNSGStatus = make_set(vmssNicHasNSG) by vmssLoadBalancerId, vmssHasPublicIPConfig, vmssSubnetIds |
| 39 | + | extend allVMSSNicsHaveNSGs = set_has_element(vmssNICsNSGStatus,False) |
| 40 | + | distinct vmssLoadBalancerId, vmssHasPublicIPConfig, allVMSSNicsHaveNSGs, vmssSubnetIds |
| 41 | + ) on $left.id == $right.vmssLoadBalancerId |
| 42 | +| extend subnetIds = set_difference(todynamic(coalesce(vmNICSubnetIds,vmssSubnetIds)),dynamic([])) // return only unique subnet ids |
| 43 | +| mv-expand subnetId = subnetIds |
| 44 | +| extend subnetId = tostring(subnetId) |
| 45 | +| project-away vmNICSubnetIds, vmssSubnetIds, subnetIds |
| 46 | +| join kind = leftouter ( |
| 47 | + resources |
| 48 | + | where type == 'microsoft.network/virtualnetworks' |
| 49 | + | mv-expand subnet = properties.subnets |
| 50 | + | extend subnetHasNatGW = isnotnull(subnet.properties.natGateway.Id) |
| 51 | + | extend subnetHasRouteTable = isnotnull(subnet.properties.routeTable.id) |
| 52 | + | extend subnetId = tostring(subnet.id) |
| 53 | + | project subnetHasNatGW, subnetHasRouteTable,subnetId |
| 54 | +) on subnetId |
| 55 | +| extend backendType = iff(isnotempty(bes),iff(isnotempty(nicLoadBalancerId),'VMs',iff(isnotempty(vmssLoadBalancerId),'VMSS','Empty')),'Empty') |
| 56 | +| extend lbHasIPv6PublicIP = iff(isnotempty(publicIPv6LBId),true,false) |
| 57 | +| project-away fes, bes, nicLoadBalancerId, vmssLoadBalancerId, publicIPv6LBId, subnetId, subnetId1 |
| 58 | +| summarize backendSubnetsHaveNATGWs = make_set(subnetHasNatGW) by id, backendPoolCount, internalOrExternal, allVMNicsHaveNSGs, allVMSSNicsHaveNSGs, publicIpCount,vmssHasPublicIPConfig,subnetHasRouteTable,backendType,lbHasIPv6PublicIP |
| 59 | +| extend allBackendSubnetsHaveNATGWs = set_has_element(backendSubnetsHaveNATGWs,False) |
| 60 | +| summarize backendSubnetsHaveRouteTables = make_set(subnetHasRouteTable) by id, backendPoolCount, internalOrExternal, allVMNicsHaveNSGs, allVMSSNicsHaveNSGs, publicIpCount,vmssHasPublicIPConfig,allBackendSubnetsHaveNATGWs,backendType,lbHasIPv6PublicIP |
| 61 | +| extend allBackendSubnetsHaveRouteTables = set_has_element(backendSubnetsHaveRouteTables, False) |
| 62 | +| project-away backendSubnetsHaveRouteTables |
| 63 | +| extend vmsHavePublicIPs = iff(publicIpCount > 0,true,false) |
| 64 | +| extend vmssHasPublicIPs = iff(isnotempty(vmssHasPublicIPConfig),vmssHasPublicIPConfig,false) |
| 65 | +| extend warningCount = 0 |
| 66 | +| extend warningCount = warningCount + iff(vmssHasPublicIPs,1,0) // vmss public IPs will change AND will require NSGs for access |
| 67 | +| extend warningCount = warningCount + iff(vmsHavePublicIPs,1,0) // VM public IPs will require NSG |
| 68 | +| extend warningCount = warningCount + iff((internalOrExternal == 'Internal' and not(vmsHavePublicIPs)),1,0) // VMs will not have outbound access (need to check natgw or nva route) |
| 69 | +| extend warningCount = warningCount + iff((internalOrExternal == 'Internal' and not(vmssHasPublicIPs)),1,0) // VMSS will not have outbound access (need to check natgw or nva route) |
| 70 | +| extend warningCount = warningCount + iff((internalOrExternal == 'External' and backendPoolCount > 1),1,0) // outbound rules will not be created automatically |
| 71 | +| extend warningCount = warningCount + iff(((vmsHavePublicIPs or internalOrExternal == 'External') and not(allVMNicsHaveNSGs)),1,0) |
| 72 | +| extend warningCount = warningCount + iff(((vmssHasPublicIPs or internalOrExternal == 'External') and not(allVMSSNicsHaveNSGs)),1,0) |
| 73 | +| extend warningCount = warningCount + iff((internalOrExternal == 'External' and not(allBackendSubnetsHaveNATGWs or allBackendSubnetsHaveRouteTables)),1,0) |
| 74 | +| extend errorCount = 0 |
| 75 | +| extend errorCount = errorCount + iff(lbHasIPv6PublicIP,1,0) |
0 commit comments