<!--startmeta
custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/integrations/azure_ip_ranges.md"
meta_yaml: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/metadata.yaml"
sidebar_label: "Azure IP Ranges"
learn_status: "Published"
learn_rel_path: "Network Performance Monitoring/Network Flows/Enrichment Methods"
keywords: ['azure', 'microsoft', 'cloud', 'ip ranges', 'service tags']
message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE FLOWS' metadata.yaml FILE"
endmeta-->

<!-- markdownlint-disable-file -->

# Azure IP Ranges


<img src="https://netdata.cloud/img/network-wired.svg" width="150"/>


Plugin: netflow-plugin
Module: azure-ip-ranges

<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />

## Overview

Annotate network flows with Azure service and region labels from Azure Service
Tags. Microsoft publishes Azure's public IP prefixes as **Service Tags JSON
files**. A service tag is Microsoft's name for a group of IP prefixes belonging
to one Azure service (e.g., `Storage`, `Sql`, `AzureFrontDoor.Backend`); the
JSON enumerates every tag together with the prefixes, the platform, and -- for
tags that support regional scope -- the Azure region.

Microsoft publishes four separate JSON files, one per Azure cloud:

- **Azure Public** -- commercial Azure, the file most users want.
- **Azure US Government** -- separate cloud for US public-sector workloads.
- **Microsoft Azure operated by 21Vianet** -- the China cloud.
- **Azure Germany** -- legacy German cloud.

This integration tags flow records to/from Azure-hosted services with
`*_NET_TENANT="azure"` plus per-region and per-service labels. Use it to
identify traffic to Azure SQL, Azure Storage, Azure Front Door, App Service,
and the rest -- without maintaining the prefix list yourself.

For the full network-identity concept (merge order, jq output shape, TLS
verification, failure modes), see
[Network Identity](https://github.com/netdata/netdata/blob/master/docs/npm/network-flows/enrichment.md).


Periodic HTTPS GET against the Service Tags JSON, jq transform via the
[jaq](https://github.com/01mf02/jaq) library, merge into the network-attributes
trie. Same mechanism as AWS / GCP IP Ranges -- different URL and JSON shape,
plus one important operational caveat documented below.


This integration is supported on all platforms.

This integration supports multiple instances configured side-by-side.


### Default Behavior

#### Auto-Detection

Disabled by default. Add an entry under enrichment.network_sources to enable.

#### Limits

One full Azure Service Tags document is fetched per refresh. Resource use scales with the number of Azure prefixes selected by your transform and the refresh interval.

#### Performance Impact

One HTTPS request per refresh interval plus a jq transform over the Azure Service Tags document. Runtime enrichment does prefix matching for source and destination IPs, and cost scales with the number of loaded network-source records.

## Setup


### Prerequisites

#### Azure publishes weekly, but the URL rotates

Microsoft updates the Service Tags JSON **weekly** (per
<https://learn.microsoft.com/en-us/azure/virtual-network/service-tags-overview#discover-service-tags-by-using-downloadable-json-files>:
"These lists are updated and published weekly"), and Microsoft asks you
to delay rolling out new prefixes for at least one week after publication
("When new IP addresses are added to service tags, they aren't used in
Azure for at least one week").

The catch: the actual download URL is **not stable**. The download portal
at <https://www.microsoft.com/en-us/download/details.aspx?id=56519> serves
a `ServiceTags_Public_<YYYYMMDD>.json` filename whose date stamp changes
every week. A naive `interval`-based fetch against last week's URL will
start 404'ing as soon as a new file is published.

You have three reasonable options, in increasing order of effort:

1. **Skip Azure IP Ranges entirely** and rely on GeoIP / ASN data
   (Microsoft's main ASN is 8075). Coarse but zero-maintenance.
2. **Use a stable redirect** if your environment provides one (some
   enterprise mirrors do).
3. **Run a small mirror script** -- a cron job that fetches the latest
   JSON via the [Service Tag Discovery REST API](https://learn.microsoft.com/en-us/rest/api/virtualnetwork/servicetags/list)
   (or `Get-AzNetworkServiceTag` in PowerShell) and writes the result to
   a stable path on an internal HTTP server. Point the plugin at that
   stable URL.

Option 3 is what most operators end up with. The Service Tag Discovery
API is authoritative and authenticated (Azure subscription with read
role); the downloadable JSON is unauthenticated but URL-rotated. Pick
whichever fits your operational model.


#### Outbound HTTPS to your mirror (or to Microsoft, if you script the URL discovery)

The plugin only needs to reach the configured `url`. Azure credentials
are needed only on the side that resolves "what's this week's URL?" --
not by the plugin itself.


#### A jq transform that matches the Service Tags schema

The Service Tags JSON has a nested shape:

```text
{
  "changeNumber": 123,
  "cloud": "Public",
  "values": [
    {
      "name": "Storage.WestUS",
      "id":   "Storage.WestUS",
      "properties": {
        "changeNumber":   456,
        "region":         "westus",
        "regionId":       30,
        "platform":       "Azure",
        "systemService":  "AzureStorage",
        "addressPrefixes": ["13.105.16.4/30", "20.150.0.0/17", ...],
        "networkFeatures": ["API", "NSG"]
      }
    },
    ...
  ]
}
```

The transform must unwrap `values[]` -> `properties.addressPrefixes[]`
and emit one object per prefix. Schema reference: `values[].name`,
`values[].id`,
`values[].properties.region` (region tag, can be empty for
cloud-wide tags like the bare `Storage`), `values[].properties.platform`,
`values[].properties.systemService` (e.g. `AzureStorage`, `AzureSql`),
`values[].properties.addressPrefixes[]` (CIDR strings, IPv4 and IPv6
mixed). Top-level `changeNumber` increments on every publication.



### Configuration

#### Options

Add a named entry under `enrichment.network_sources` pointing at your
stable mirror URL (or, with the limitations above, at this week's
`ServiceTags_Public_<date>.json` URL).


<details open><summary>Config options</summary>



| Option | Description | Default | Required |
|:-----|:------------|:--------|:---------:|
| url | Stable URL to your locally-mirrored Azure Service Tags JSON, or this week's date-stamped Microsoft URL. |  | yes |
| interval | How often to fetch. Microsoft publishes weekly; daily is plenty. | 60s (loop floor) | no |
| timeout | Per-request timeout. Service Tags JSON files are large (tens of MB) -- give it room. | 60s | no |
| transform | jq expression that maps `values[].properties.addressPrefixes[]` into per-prefix objects. | . | yes |


</details>



#### via File

The configuration file name for this integration is `netflow.yaml`.


You can edit the configuration file using the [`edit-config`](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#edit-configuration-files) script from the
Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#locate-your-config-directory).

```bash
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
```

##### Examples

###### Azure Public via internal mirror -- tag by region and service

Internal mirror serving the latest Public-cloud Service Tags JSON.
Tags every Azure prefix with `tenant=azure`, the region, and the
lowercase systemService name as the role.


```yaml
enrichment:
  network_sources:
    azure:
      url: "https://internal.example/azure-service-tags.json"
      interval: 24h
      timeout: 60s
      transform: |
        .values[]
        | .properties as $p
        | $p.addressPrefixes[]
        | {
            prefix: .,
            tenant: "azure",
            region: ($p.region // ""),
            role:   (($p.systemService // "") | ascii_downcase)
          }

```
###### Azure Storage only

Filter to a single Azure systemService for narrower tagging.

<details open><summary>Config</summary>

```yaml
enrichment:
  network_sources:
    azure-storage:
      url: "https://internal.example/azure-service-tags.json"
      interval: 24h
      transform: |
        .values[]
        | select(.properties.systemService == "AzureStorage")
        | .properties as $p
        | $p.addressPrefixes[]
        | {
            prefix: .,
            tenant: "azure",
            role:   "storage",
            region: ($p.region // "")
          }

```
</details>

###### Azure US Government cloud

The US Government cloud is published as a separate JSON file with its
own download ID (57063). Same schema as the Public cloud; tag tenant
differently so you can tell them apart in dashboards.


<details open><summary>Config</summary>

```yaml
enrichment:
  network_sources:
    azure-usgov:
      url: "https://internal.example/azure-service-tags-usgov.json"
      interval: 24h
      transform: |
        .values[]
        | .properties as $p
        | $p.addressPrefixes[]
        | {
            prefix: .,
            tenant: "azure-usgov",
            region: ($p.region // ""),
            role:   (($p.systemService // "") | ascii_downcase)
          }

```
</details>



### 404 a week after deploy

You configured `url` against `ServiceTags_Public_<date>.json` directly.
Microsoft rotates the date stamp weekly, so the URL stops resolving
within a week. Move to an internal mirror that resolves the latest URL
each cycle, or to the Service Tag Discovery REST API
(<https://learn.microsoft.com/en-us/rest/api/virtualnetwork/servicetags/list>)
fed into a static file.


### Empty results from the transform

The Service Tags JSON is nested two levels deep
(`values[].properties.addressPrefixes[]`). If the jq doesn't unwrap
both levels, every fetch yields zero rows and the source backs off as if
it errored. Test the jq locally with `jq < azure-service-tags.json` and
confirm at least one `{prefix, tenant, ...}` object comes out.


### Service Tag API data lags the JSON file

Per Microsoft's note on the Service Tags overview page, "It takes up to
four weeks for new Service Tag data to propagate in the API results
across all Azure regions". If you mirror via the REST API, expect newly
added tags to appear in the JSON download a few weeks before the API,
not the other way around. For prefix tagging this rarely matters; for
firewall rules it can.


### TLS verification cannot be disabled

`tls.skip_verify: true` is rejected by validation. Use `tls.ca_file`
for custom-CA paths (e.g., on an internal mirror with a private CA).
