Skip to main content

Command Palette

Search for a command to run...

Rolling out VNet flow logs and traffic analytics with EPAC across landing zones

Updated
4 min readView as Markdown

Why look beyond firewall logs

Network monitoring beyond what flows through your firewall or NVA gives you a more holistic view of your traffic — patterns, trends, and what never touches the firewall in the first place. That's where VNet flow logs and traffic analytics come in.

Why VNet flow logs and Traffic Analytics

VNet flow logs is a Network Watcher feature that captures network traffic for a Virtual Network and writes the raw output to a blob container in a designated storage account. This feature can be enabled at a VNet, subnet, or NIC level. The logs on their own aren't very useful, but paired with Traffic Analytics, the picture is clearer.

Traffic Analytics is what turns them into something you can work with, it ingests the raw logs, enriches them, and lands them in a Log Analytics workspace where you can query and visualise the data. A built-in dashboard covers the common views out of the box. Information such as allowed vs blocked, top talkers, and threat hits.

why bother enabling them

Each platform team should weigh the monitoring value setting this solution up against the cost — storage and Log Analytics ingestion aren't free, so decide before enabling broadly. A few questions that can help out:

  1. Do we need visibility into Azure traffic that does not traverse our firewall?

  2. Do we need to troubleshoot workload connections — for example, from an Azure workload to a private endpoint?

  3. Do we need visibility into inter-VNet traffic?

Automating deployment with Azure Policy

In an enterprise environment with several spoke networks that each need a Network Watcher, you'll want to automate the deployment. Azure Policy has a built-in policy definition that does exactly that: Configure virtual network to enable Flow Log and Traffic Analytics.

Configuring this with Enterprise Policy as Code (EPAC) requires a policy assignment at your target scope that references the built-in policy.

A few things worth knowing about the assignment:

  1. policyId hooks up the assignment with the correct policy definition

  2. Flow logs are enabled per region, so each region needs its own assignment.

  3. networkWatcherRG and networkWatcherName values are hardcoded (explained below)

  4. Retention can be 30 or 60 days.

  5. You can centralise both: raw logs to a shared storage account, Traffic Analytics to a shared Log Analytics workspace.

{
  "$schema": "https://raw.githubusercontent.com/Azure/enterprise-azure-policy-as-code/main/Schemas/policy-assignment-schema.json",
  "nodeName": "/root",
  "definitionEntry": {
    "policyId": "/providers/Microsoft.Authorization/policyDefinitions/3e9965dc-cc13-47ca-8259-a4252fd0cf7b",
    "displayName": "Configure virtual network to enable Flow Log and Traffic Analytics"
  },
  "assignment": {
    "name": "Configure VNet Flow Logs and Traffic Analytics - Norway East",
    "displayName": "Configure VNet Flow Logs and Traffic Analytics - <REGION>",
    "description": "Deploys and enables VNet flow logs with Traffic Analytics for virtual networks in the specified region. Flow logs are written to a central storage account and Traffic Analytics data is sent to a Log Analytics workspace. Each subscription hosts its own Network Watcher flow log resource."
  },
  "metadata": {
    "assignedBy": "epac/<ID>/prod"
  },
  "parameters": {
    "effect": "DeployIfNotExists",
    "vnetRegion": "norwayeast",
    "storageId": "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Storage/storageAccounts/<STORAGE_ACCOUNT>",
    "timeInterval": "60",
    "workspaceResourceId": "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.OperationalInsights/workspaces/<LOG_ANALYTICS_WORKSPACE>",
    "workspaceRegion": "<REGION>",
    "networkWatcherRG": "NetworkWatcherRG",
    "networkWatcherName": "NetworkWatcher_norwayeast",
    "retentionDays": "30"
  },
  "scope": {
    "prod": [
      "/providers/Microsoft.Management/managementGroups/<MANAGEMENT_GROUP>"
    ]
  }
}

The naming-consistency dependency

At one VNet, most of these are quirks. Across dozens of subscriptions and Virtual Networks, they're the difference between a working rollout and a broken one.

For this to scale, the values networkWatcherRGand networkWatcherName must match across subscriptions where there is a VNet you want to set up flow logs and Traffic Analytics. The assignment explicitly checks for Network Watchers in a Resource Group following this naming standard and if conditions are met the DeployIfNotExists effect will trigger. The compliance page will help you narrow down whether a subscription is missing the Resource Group entirely, or has the Resource Group but is missing the Network Watcher.

A couple of smaller things worth knowing

Storage accounts can be private

You might expect flow logs to require public network access on the storage account. They don't — you can lock the storage account down and put the blob service behind a private endpoint. Flow logs will still write.

Data Collection Rule (DCR) and Data Collection Endpoint (DCE)

Traffic Analytics deploys a Data Collection Rule and Data Collection Endpoint into the resource group containing the Log Analytics workspace. If you tightly control which resource types are allowed at that scope, make sure both are permitted. I had some issues debugging this part, because it does not show up in Activity Logs.