Azure Sentinel Cost Optimization with KQL Tips

Do you know the difference between a successful implementation and a failed implementation in the cloud? Costs! This post focus on Azure Sentinel Cost Optimization with KQL Tips.

Cloud costs are critical, and even they have a specific role nowadays with a whole methodology. Of course, this is also true in the Azure Sentinel. The following article focuses on the possibilities (a few of them) of cloud costs and few tips that can help daily.

Until the full post on Azure Sentinel Optimization Costs comes up, I’m writing down a short post with few queries that will help you manage costs correctly on Azure Sentinel.

First, you must know which table you’ve got on your Azure Sentinel (Log Analytics workspace) and then continue to the cost queries. Let’s play with KQL.

The basic Azure Sentinel billing model is cloud-friendly, consumption-based pricing. You only pay for what you use. Pricing details are available for alerting, metrics, notifications, Log Analytics, and Application Insights.

Azure Sentinel costs are based on the following paid Azure services:

  • Azure Sentinel service
  • Log Analytics
  • Logic Apps

Cost Optimization with KQL

First, we must know which table we’ve got on the Log Analytics workspace and then export the tables list and use it on other queries.

Azure Sentinel Tables list, and first, let’s run a basic query for the tables list and then export the list.

search *
| where TimeGenerated > ago(31d)
| summarize count() by $table
| sort by count_ desc
| render piechart 

Azure Sentinel Cost with KQL

TIP: you can export the information to a CSV file, and you will need this list for the following queries. 

Azure Sentinel cost and pricing for billable data and with the dedicated price, Based on the table.

//Based on the Azure Sentinel Pricing
let aap = 2.30;
union isfuzzy=true withsource = tt *
| where TimeGenerated > ago(31d)
| where _IsBillable == True
| where tt in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| summarize
TotalGBytes =round( sum(_BilledSize/(1024*1024*1024)),2),
EstimatedCostUSD=round(aap * sum(_BilledSize/(1024*1024*1024)),2)
by Solution=tt
| sort by TotalGBytes desc

TIP: you can change the table list for any scenario

Azure Sentinel Cost

Azure Sentinel for all tables on the list, including billable data

//Based on the Azure Sentinel Pricing
let aap = 2.20;
union isfuzzy=true withsource = tt *
| where TimeGenerated > ago(31d)
| where tt in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| summarize
TotalGBytes =round( sum(_BilledSize/(1024*1024*1024)),2),
EstimatedCostUSD=round(aap * sum(_BilledSize/(1024*1024*1024)),2)
by Solution=tt
| sort by TotalGBytes desc

Azure Sentinel Billable Data

We always add some graph to the game with the line: | render a barchart 

Azure Sentinel cost-based nodes and can be daily or hourly. The bills for nodes with hourly granularity don’t count nodes, only sending a set of dedicated data types.

find where TimeGenerated >= startofday(ago(31d)) and TimeGenerated < startofday(now())
project Computer, _IsBillable, Type, TimeGenerated
| where Type !in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| extend computerName = tolower(tostring(split(Computer, ‘.’)[0]))
| where computerName != “”
| where _IsBillable == true
| summarize billableNodesPerHour=dcount(computerName) by bin(TimeGenerated, 1h)
| summarize billableNodesPerDay = sum(billableNodesPerHour)/24., billableNodeMonthsPerDay = sum(billableNodesPerHour)/24./31. by day=bin(TimeGenerated, 1d)
| sort by billableNodesPerDay desc

Azure Sentinel Billable Data

Azure Sentinel Usage is another tool that can help you with the essential cost, but to find the little thing, you must use the KQL.

All queries are available at the following repo https://github.com/eshlomo1/Azure-Sentinel-4-SecOps/tree/master/Cost

But wait, from where to start? Next post, I will describe how to plan the cost and more tips to optimize for cost.

Azure Sentinel Cost with KQL

More post about Azure Sentinel – Elli Shlomo (eshlomo.us)

Azure Sentinel Cost Optimization with KQL Tips

Do you know the difference between a successful implementation and a failed implementation in the cloud? Costs! This post focus on Azure Sentinel Cost Optimization with KQL Tips.
Cloud costs are critical, and even they have a specific role nowadays with a whole methodology. Of course, this is also true in the Azure Sentinel. The following article focuses on the possibilities (a few of them) of cloud costs and few tips that can help daily.
Until the full post on Azure Sentinel Optimization Costs comes up, I’m writing down a short post with few queries that will help you manage costs correctly on Azure Sentinel.
First, you must know which table you’ve got on your Azure Sentinel (Log Analytics workspace) and then continue to the cost queries. Let’s play with KQL.
The basic Azure Sentinel billing model is cloud-friendly, consumption-based pricing. You only pay for what you use. Pricing details are available for alerting, metrics, notifications, Log Analytics, and Application Insights.
Azure Sentinel costs are based on the following paid Azure services:

  • Azure Sentinel service
  • Log Analytics
  • Logic Apps

Cost Optimization with KQL

First, we must know which table we’ve got on the Log Analytics workspace and then export the tables list and use it on other queries.
Azure Sentinel Tables list, and first, let’s run a basic query for the tables list and then export the list.

search *
| where TimeGenerated > ago(31d)
| summarize count() by $table
| sort by count_ desc
| render piechart 

Azure Sentinel Cost with KQL
TIP: you can export the information to a CSV file, and you will need this list for the following queries. 
Azure Sentinel cost and pricing for billable data and with the dedicated price, Based on the table.

//Based on the Azure Sentinel Pricing
let aap = 2.30;
union isfuzzy=true withsource = tt *
| where TimeGenerated > ago(31d)
| where _IsBillable == True
| where tt in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| summarize
TotalGBytes =round( sum(_BilledSize/(1024*1024*1024)),2),
EstimatedCostUSD=round(aap * sum(_BilledSize/(1024*1024*1024)),2)
by Solution=tt
| sort by TotalGBytes desc

TIP: you can change the table list for any scenario
Azure Sentinel Cost
Azure Sentinel for all tables on the list, including billable data

//Based on the Azure Sentinel Pricing
let aap = 2.20;
union isfuzzy=true withsource = tt *
| where TimeGenerated > ago(31d)
| where tt in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| summarize
TotalGBytes =round( sum(_BilledSize/(1024*1024*1024)),2),
EstimatedCostUSD=round(aap * sum(_BilledSize/(1024*1024*1024)),2)
by Solution=tt
| sort by TotalGBytes desc

Azure Sentinel Billable Data
We always add some graph to the game with the line: | render a barchart 

Azure Sentinel cost-based nodes and can be daily or hourly. The bills for nodes with hourly granularity don’t count nodes, only sending a set of dedicated data types.

find where TimeGenerated >= startofday(ago(31d)) and TimeGenerated < startofday(now())
project Computer, _IsBillable, Type, TimeGenerated
| where Type !in
(
“Perf”, “Event”, “DeviceEvents”, ” SecurityEvent”, ” DeviceNetworkEvents”,
“DeviceFileEvents”, ” DeviceProcessEvents”, ” DeviceFileCertificateInfo”, ” SecurityRegulatoryCompliance”,
“AADNonInteractiveUserSignInLogs”, ” AzureActivity”, ” DeviceRegistryEvents”, ” DeviceNetworkInfo”,
“ADCSV_CL”, ” AD_Metadata_CL”, ” DeviceImageLoadEvents”, ” Usage”, ” OfficeActivity”, ” Operation”,
” Heartbeat”, ” DeviceInfo”, ” DeviceLogonEvents”, ” SigninLogs”, ” DnsEvents”, ” SecurityBaseline”,
” UserPeerAnalytics”, ” AuditLogs”, ” SecurityRecommendation”, ” SecurityAlert”, ” UserAccessAnalytics”,
“SecurityIncident”, ” AADManagedIdentitySignInLogs”, ” ADDS_Metadata_CL”, ” SecureScores”,
” Update”, ” SecurityNestedRecommendation”, ” SecureScoreControls”, ” DnsInventory”, ” ProtectionStatus”,
“SecurityDetection”, ” AADServicePrincipalSignInLogs”, ” ComputerGroup”, ” UpdateSummary”, ” AD_Metadata1_CL”, ” SecurityBaselineSummary”
)
| extend computerName = tolower(tostring(split(Computer, ‘.’)[0]))
| where computerName != “”
| where _IsBillable == true
| summarize billableNodesPerHour=dcount(computerName) by bin(TimeGenerated, 1h)
| summarize billableNodesPerDay = sum(billableNodesPerHour)/24., billableNodeMonthsPerDay = sum(billableNodesPerHour)/24./31. by day=bin(TimeGenerated, 1d)
| sort by billableNodesPerDay desc

Azure Sentinel Billable Data
Azure Sentinel Usage is another tool that can help you with the essential cost, but to find the little thing, you must use the KQL.

All queries are available at the following repo https://github.com/eshlomo1/Azure-Sentinel-4-SecOps/tree/master/Cost
But wait, from where to start? Next post, I will describe how to plan the cost and more tips to optimize for cost.
Azure Sentinel Cost with KQL
More post about Azure Sentinel – Elli Shlomo (eshlomo.us)

You may also like...

3 Responses

  1. Darren Pritchard says:

    This is really useful stuff – thank you. Any chance you have the Queries saved somewhere? I cannot select and copy form this page to try them out. thanks

  2. Ragu says:

    Waiting for your next post on cost optimization.

  1. February 27, 2021

    […] Azure Sentinel Cost Optimization KQL Tips […]

Leave a Reply

error: Content is Protected !!
%d