Plugin: netflow-plugin Module: azure-ip-ranges
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:
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.
Periodic HTTPS GET against the Service Tags JSON, jq transform via the 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 only supported on the following platforms:
This integration supports multiple instances configured side-by-side.
Disabled by default. Add an entry under enrichment.network_sources to enable.
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.
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.
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:
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.
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.
The Service Tags JSON has a nested shape:
{
"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.
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).
| 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 |
The configuration file name for this integration is netflow.yaml.
You can edit the configuration file using the edit-config script from the
Netdata config directory.
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
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.
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)
}
Filter to a single Azure systemService for narrower tagging.
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 // "")
}
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.
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)
}
Tags flow records with *_NET_TENANT, *_NET_REGION, *_NET_ROLE when the
source or destination IP matches an Azure prefix. Verify on the Network Flows
tab via the *_NET_* columns. Country / state / city overrides
(*_COUNTRY, *_GEO_STATE, *_GEO_CITY) are also available if your
transform sets them, but Service Tags don’t carry country/state/city data –
only region codes like westus or northeurope.
There are no alerts configured by default for this integration.
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.
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.
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.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).
Want a personalised demo of Netdata for your use case?