FinOps best practices for Networking

This article outlines proven FinOps practices for networking services. They focus on cost optimization, efficiency improvements, and resource insights.


Azure Firewall

The following sections provide Azure Resource Graph (ARG) queries for Azure Firewall. These queries help you gain insights into your Azure firewall resources and ensure they're configured with the appropriate settings. By analyzing usage patterns and surfacing recommendations from Azure Advisor, you can optimize your Azure firewall configurations for cost efficiency.

Query: Azure firewall and firewall policies analysis

This ARG query analyzes Azure firewalls and their associated firewall policies within your Azure environment. It specifically targets firewalls with a premium SKU tier and verifies that the configurations in their associated firewall policies are utilizing the premium features.

Category

Optimization

Query

resources 
| where type =~ 'Microsoft.Network/azureFirewalls' and properties.sku.tier=="Premium"
| project FWID=id, firewallName=name, SkuTier=tostring(properties.sku.tier), resourceGroup, location
| join kind=inner (
    resources
    | where type =~ 'microsoft.network/firewallpolicies'
    | mv-expand properties.firewalls
    | extend intrusionDetection = tostring(properties.intrusionDetection contains "Alert"
        or properties.intrusionDetection contains "Deny")
    | extend transportSecurity = tostring(properties.transportSecurity contains "keyVaultSecretId")
    | extend FWID = tostring(properties_firewalls.id)
    | where intrusionDetection == "False"
        and transportSecurity == "False"
    | project
        PolicyName = name,
        PolicySKU = tostring(properties.sku.tier),
        intrusionDetection,
        transportSecurity,
        FWID
) on FWID

Query: Azure Firewall and associated subnets analysis

This ARG query analyzes Azure firewalls and their associated subnets within your Azure environment. It provides insights into which subnets are associated with each Azure firewall instance. Optimize the use of Azure firewall by having a central instance of Azure firewall in the hub virtual network or Virtual WAN secure hub. Then share the same firewall across many spoke virtual networks that are connected to the same hub from the same region.

Category

Optimization

Query

resources
| where type =~ 'Microsoft.Network/azureFirewalls' and properties.sku.tier=="Premium"
| project
    FWID=id,
    firewallName=name,
    SkuTier=tostring(properties.sku.tier),
    resourceGroup,
    location
| join kind=inner (
    resources
    | where type =~ 'microsoft.network/firewallpolicies'
    | mv-expand properties.firewalls
    | extend intrusionDetection = tostring(properties.intrusionDetection contains "Alert"
        or properties.intrusionDetection contains "Deny")
    | extend transportSecurity = tostring(properties.transportSecurity contains "keyVaultSecretId")
    | extend FWID=tostring(properties_firewalls.id)
    | where intrusionDetection == "False"
        and transportSecurity == "False"
    | project
        PolicyName = name,
        PolicySKU = tostring(properties.sku.tier),
        intrusionDetection,
        transportSecurity,
        FWID
) on FWID

Application Gateway

The following section provides an ARG queries for Azure Application Gateway. It helps you gain insights into your Azure Application Gateway resources and ensure they're configured with the appropriate settings.

Query: Idle application gateways

This ARG query analyzes application gateways and their associated backend pools within your Azure environment. It provides insights into which application gateways have empty backend pools, indicating they might be idle and potentially unnecessary.

Category

Optimization

Query

resources
| where type =~ 'Microsoft.Network/applicationGateways'
| extend
    backendPoolsCount = array_length(properties.backendAddressPools),
    SKUName = tostring(properties.sku.name),
    SKUTier = tostring(properties.sku.tier),
    SKUCapacity = properties.sku.capacity,
    backendPools = properties.backendAddressPools,
    resourceGroup = strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)
| project id, name, SKUName, SKUTier, SKUCapacity, resourceGroup, subscriptionId
| join (
    resources
    | where type =~ 'Microsoft.Network/applicationGateways'
    | mvexpand backendPools = properties.backendAddressPools
    | extend backendIPCount = array_length(backendPools.properties.backendIPConfigurations)
    | extend backendAddressesCount = array_length(backendPools.properties.backendAddresses)
    | extend backendPoolName = backendPools.properties.backendAddressPools.name
    | summarize
        backendIPCount = sum(backendIPCount),
        backendAddressesCount = sum(backendAddressesCount)
        by id
) on id
| project-away id1
| where (backendIPCount == 0 or isempty(backendIPCount))
    and (backendAddressesCount==0 or isempty(backendAddressesCount))
| order by id asc

ExpressRoute

The following section provides an ARG query for ExpressRoute. It helps you gain insights into your ExpressRoute circuits and ensure they're configured with the appropriate settings.

Query: Idle ExpressRoute circuits

This ARG query analyzes ExpressRoute circuits within your Azure environment to identify any without a completed circuit.

Category

Optimization

Query

resources
| where type =~ 'Microsoft.Network/expressRouteCircuits'
    and properties.serviceProviderProvisioningState == "NotProvisioned"
| extend
    ServiceLocation = tostring(properties.serviceProviderProperties.peeringLocation),
    ServiceProvider = tostring(properties.serviceProviderProperties.serviceProviderName),
    BandwidthInMbps = tostring(properties.serviceProviderProperties.bandwidthInMbps)
| project
    ERId = id,
    ERName = name,
    ERRG = resourceGroup,
    SKUName = tostring(sku.name),
    SKUTier = tostring(sku.tier),
    SKUFamily = tostring(sku.family),
    ERLocation = location,
    ServiceLocation,
    ServiceProvider,
    BandwidthInMbps

Load Balancer

The following section provides an ARG query for Azure Load Balancer. It helps you gain insights into your Azure load balancer resources and ensure they're configured with the appropriate settings.

Query: Idle load balancers

This ARG query analyzes Azure load balancers and their associated backend pools within your Azure environment. It provides insights into which load balancers have empty backend pools, indicating they might be idle and potentially unnecessary.

Category

Optimization

Query

resources
| extend resourceGroup = strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)
| extend SKUName = tostring(sku.name)
| extend SKUTier = tostring(sku.tier)
| extend location,backendAddressPools = properties.backendAddressPools
| where type =~ 'microsoft.network/loadbalancers'
    and array_length(backendAddressPools) == 0
    and sku.name!='Basic'
| order by id asc
| project
    id,
    name,
    SKUName,
    SKUTier,
    backendAddressPools,
    location,
    resourceGroup,
    subscriptionId

Private DNS

The following section provides an ARG query for Private DNS. It helps you gain insights into your Private DNS resources and ensure they're configured with the appropriate settings.

Query: Private DNS

This ARG query analyzes Private DNS zones within your Azure environment to identify any without Virtual Network Links.

Category

Optimization

Query

resources
| where type == "microsoft.network/privatednszones"
    and properties.numberOfVirtualNetworkLinks == 0
| project id, PrivateDNSName=name,
    NumberOfRecordSets = tostring(properties.numberOfRecordSets),
    resourceGroup = tostring(strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)),
    vNets = tostring(properties.properties.numberOfVirtualNetworkLinks),
    subscriptionId

Public IP address

The following sections provide ARG queries for public IP addresses. They help you gain insights into your public IP address resources and ensure they're configured with the appropriate settings.

Query: Idle public IP addresses

This ARG query analyzes Azure public IP addresses. It provides insights into which public IPs are idle and potentially unnecessary.

Category

Optimization

Query

resources
| where type =~ 'Microsoft.Network/publicIPAddresses'
    and isempty(properties.ipConfiguration)
    and isempty(properties.natGateway)
    and properties.publicIPAllocationMethod =~ 'Static'
| extend
    PublicIpId = id,
    IPName = name,
    AllocationMethod = tostring(properties.publicIPAllocationMethod),
    SKUName = sku.name,
    Location = location,
    resourceGroup = strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)
| project PublicIpId, IPName, SKUName, resourceGroup, Location, AllocationMethod, subscriptionId
| union (
    Resources
    | where type =~ 'microsoft.network/networkinterfaces'
        and isempty(properties.virtualMachine)
        and isnull(properties.privateEndpoint)
        and isnotempty(properties.ipConfigurations)
    | extend IPconfig = properties.ipConfigurations
    | mv-expand IPconfig
    | extend PublicIpId= tostring(IPconfig.properties.publicIPAddress.id)
    | project PublicIpId
    | join (
        resource
        | where type =~ 'Microsoft.Network/publicIPAddresses'
        | extend
            PublicIpId = id,
            IPName = name,
            AllocationMethod = tostring(properties.publicIPAllocationMethod),
            SKUName = sku.name,
            resourceGroup,
            Location = location
    ) on PublicIpId
    | project
        PublicIpId,
        IPName,
        SKUName,
        resourceGroup,
        Location,
        AllocationMethod,
        subscriptionId
)

Query: Identify public IP addresses routing method

This ARG query analyzes public IP addresses and identifies the routing method, allocation method, and SKU. It also analyzes other details of public IP addresses that are associated with an IP configuration.

Category

Optimization

Query

resources
| where type =~ 'Microsoft.Network/publicIPAddresses'
    and isnotempty(properties.ipConfiguration)
| where tostring(properties.ipTags) == "[]"
| extend
    PublicIpId = id,
    RoutingMethod = id,
    IPName = name,
    AllocationMethod = tostring(properties.publicIPAllocationMethod),
    SKUName = sku.name,
    Location = location,
    resourceGroup = strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)
| project
    PublicIpId,
    IPName,
    RoutingMethod,SKUName,
    resourceGroup,
    Location,
    AllocationMethod,
    subscriptionId

Query: Check public IP addresses' DDoS protection policy

If you need to protect fewer than 15 public IP resources, the IP protection tier is the more cost-effective option. However, if you have more than 15 public IP resources to protect, then the network protection tier becomes more cost-effective.

Category

Optimization

Query

resources
| where type == "microsoft.network/publicipaddresses"
| project ddosProtection = tostring(properties.ddosSettings), name
| where ddosProtection has "Enabled"
| count
| project TotalIpsProtected = Count
| extend CheckIpsProtected = iff(TotalIpsProtected >= 15, "Enable Network Protection tier", "Enable PIP DDoS Protection")

Virtual Network Gateway

The following sections provide ARG queries for Virtual Network Gateways. They help you gain insights into your Virtual Network Gateway resources and ensure they're configured with the appropriate settings.

Query: Check for idle Virtual Network Gateway

This ARG query analyzes Virtual Network Gateways within your Azure environment to identify any that are idle.

Category

Optimization

Query

resources
| where type == "microsoft.network/virtualnetworkgateways"
| extend resourceGroup = strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)
| project id, GWName=name, resourceGroup, location, subscriptionId
| join kind = leftouter(
    resources
    | where type == "microsoft.network/connections"
    | extend id = tostring(properties.virtualNetworkGateway1.id)
    | project id
) on id
| where isempty(id1)
| project
    id,
    GWName,
    resourceGroup,
    location,
    subscriptionId,
    status=id

Query: Check for idle NAT gateway

This ARG query analyzes NAT gateways within your Azure environment to identify any that are idle.

Category

Optimization

Query

resources
| where type == "microsoft.network/natgateways" and isnull(properties.subnets)
| project
    id,
    GWName = name,
    SKUName = tostring(sku.name),
    SKUTier = tostring(sku.tier),
    Location = location,
    resourceGroup = tostring(strcat('/subscriptions/', subscriptionId, '/resourceGroups/', resourceGroup)),
    subnet = tostring(properties.subnet),
    subscriptionId

Looking for more?

Did we miss anything? Would you like to see something added? We'd love to hear about any questions, problems, or solutions you'd like to see covered here. Create a new issue with the details that you'd like to see either included here.


Related resources:

Related solutions: