Skip to main content

AWS IP Ranges

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

Overview

Annotate network flows with AWS service and region labels from AWS public IP ranges. AWS publishes its current public IP allocations as a single JSON document at https://ip-ranges.amazonaws.com/ip-ranges.json. The file lists every prefix AWS uses for a published service, tagged with the AWS region and the AWS service that owns the prefix (AMAZON, EC2, S3, CLOUDFRONT, API_GATEWAY, ...). This integration fetches the file periodically, transforms it via a jq expression, and labels matching flow records with provider, region, and service tags.

Once configured, traffic to / from AWS shows up in dashboards as tenant=amazon with per-region (region=us-east-1, region=eu-central-1, ...) and per-service (role=s3, role=cloudfront, ...) breakdown. This is complementary to GeoIP and ASN enrichment: instead of a flow being labeled simply AS16509 Amazon, it becomes labeled with the specific AWS service and region carrying the traffic -- without parsing AS-name strings.

The file is public; no AWS credentials are needed.

Schema of ip-ranges.json:

  • top-level: syncToken, createDate, prefixes, ipv6_prefixes
  • each entry in prefixes[]: ip_prefix, region, service, network_border_group
  • each entry in ipv6_prefixes[]: ipv6_prefix, region, service, network_border_group

For the cross-cutting concepts (how multiple network sources merge, the lookup priority vs static networks config, TLS verification rules, the jq engine and its expected output schema, fetch loop and retry/backoff), see Network Identity.

The plugin issues a periodic GET to https://ip-ranges.amazonaws.com/ip-ranges.json, parses the JSON body, runs the configured jq transform via the jaq library, and merges the resulting prefix-labeled rows into the network-attributes trie shared by all enrichment sources.

AWS does not publish a fixed refresh cadence; the file is updated whenever the AWS IP space changes (typically several times per day) and the syncToken / createDate fields advance on every change. AWS recommends polling no faster than the file actually changes; daily is enough for most flow-attribution use cases. The plugin floors the configured interval at 60s.

This integration is only supported on the following platforms:

  • Linux

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 AWS prefix document is fetched per refresh. Resource use scales with the number of AWS prefixes selected by your transform and the refresh interval.

Performance Impact

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

Setup

Prerequisites

Outbound HTTPS to AWS

The agent host must be able to reach https://ip-ranges.amazonaws.com/ip-ranges.json. No AWS credentials are needed -- the file is public.

Configuration

Options

Add a named entry under enrichment.network_sources. The map key (e.g. aws) is the source name; it is used in plugin logs but is not automatically attached to flow records -- the record labels come entirely from your transform output (tenant, region, role, name, site, city, country, state, asn, asn_name).

The expected transform output is a stream of objects, each carrying a prefix (CIDR string) plus any subset of the optional attribute fields. See the cross-cutting Network Identity page for the full output schema.

Config options
OptionDescriptionDefaultRequired
urlAWS publishes the master file at this URL. Use it as-is unless you mirror it locally for air-gapped environments.https://ip-ranges.amazonaws.com/ip-ranges.jsonyes
intervalHow often to fetch the file. AWS updates the document whenever its IP space changes (often several times per day, sometimes more); daily is enough for most uses. The configured value is floored at 60s.60sno
timeoutPer-request timeout for the HTTPS GET.60sno
methodHTTP method. AWS serves the file via GET; leave at the default.GETno
headersExtra HTTP headers added to the request. Not required for the public AWS URL; only needed if you front the file behind your own authenticated mirror.{}no
transformjq expression (compiled by jaq) that converts the AWS JSON into a stream of {prefix, ...} objects. The default . does not match the AWS schema -- you must supply a real transform (see examples below) or fetches fail because output rows cannot be mapped to the required {prefix, ...} schema..yes

via File

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
Examples
Tag all AWS prefixes by region and service (IPv4 + IPv6)

Recommended starting point. Sets tenant=amazon, region=<aws-region>, role=<service-name-lowercased>. Covers both prefixes[] and ipv6_prefixes[] in one stream so v4 and v6 traffic are tagged consistently.

enrichment:
network_sources:
aws:
url: "https://ip-ranges.amazonaws.com/ip-ranges.json"
interval: 24h
timeout: 60s
transform: |
(.prefixes + .ipv6_prefixes)[] | {
prefix: (.ip_prefix // .ipv6_prefix),
tenant: "amazon",
region: .region,
role: (.service | ascii_downcase)
}

AWS S3 only

Filter to a single AWS service for narrower tagging. Useful when you only care about identifying S3 traffic (e.g. egress-cost attribution).

Config
enrichment:
network_sources:
aws-s3:
url: "https://ip-ranges.amazonaws.com/ip-ranges.json"
interval: 24h
transform: |
(.prefixes + .ipv6_prefixes)[]
| select(.service == "S3")
| {
prefix: (.ip_prefix // .ipv6_prefix),
tenant: "amazon",
role: "s3",
region: .region
}

Use network_border_group as the site label

AWS exposes a network_border_group field that distinguishes Local Zones / Wavelength Zones from the parent Region. Map it to the site attribute if you want that distinction visible in flow dashboards.

Config
enrichment:
network_sources:
aws:
url: "https://ip-ranges.amazonaws.com/ip-ranges.json"
interval: 24h
transform: |
(.prefixes + .ipv6_prefixes)[] | {
prefix: (.ip_prefix // .ipv6_prefix),
tenant: "amazon",
region: .region,
site: .network_border_group,
role: (.service | ascii_downcase)
}

Default transform: "." fails because output rows are missing prefix

The default . returns the raw JSON object, not the per-prefix stream the plugin expects. You must supply a transform that yields one object per prefix (with at least a prefix field). Use the first example above as your starting template.

AWS service name precedence inside one prefix

AWS sometimes lists the same ip_prefix under multiple service entries (e.g. once under AMAZON and again under EC2). The plugin merges all records into a single prefix trie, and the last write wins for a given prefix length. If you want a specific service to take precedence, filter the transform with select(.service != "AMAZON") so the broader catch-all entries are dropped.

Static networks: config silently overrides AWS labels

When a prefix is defined in both this source and enrichment.networks, the static config wins on every non-empty field. This is by design (operator intent overrides imported data) but can surprise operators who expect the remote feed to be authoritative. See the cross-cutting Network Identity page for the full lookup-priority rules.

Empty result from the transform is treated as failure

If the jq filter happens to produce nothing (bad selector, wrong field name, upstream JSON shape change), the source backs off as if it errored. Check the journal for network-sources warnings: journalctl --namespace netdata | grep network-sources.

TLS verification cannot be disabled

tls.skip_verify: true is rejected by validation. Use tls.ca_file for custom-CA paths if you front AWS behind an internal TLS-terminating proxy with a private CA.


Do you have any feedback for this page? If so, you can open a new issue on our netdata/learn repository.