Docs
AWS VPC IPAM

Technical Information

AWS VPC IPAM to NetBox object mapping

The integration queries the AWS EC2 IPAM APIs and emits three NetBox object types through Diode: VRF, Prefix, and IPAddress. No Tenant, Manufacturer, or custom field objects are created.

Object type mapping table

AWS sourceNetBox objectKey attributes
IPAM scopeVRF (scope VRF)name from the scope Name tag, or the scope ID when the tag is unset; rd = ScopeID: + last 13 characters of the scope ID; description = Scope ARN: <arn> Type: <private|public>; enforce_unique = true
VPC (from a resource CIDR carrying a VpcId)VRF (VPC VRF)name = the VpcId (for example vpc-0e941a95795989166); rd = VPC: + last 13 characters of the VPC ID; no description; enforce_unique = true
IPAM pool provisioned CIDR (get_ipam_pool_cidrs)Prefixprefix = the provisioned CIDR; vrf = scope VRF; is_pool = true; description = Provisioned from IPAM Pool <pool_id>, carrying the pool's name and description when set
IPAM pool allocation (get_ipam_pool_allocations)Prefixprefix = the allocated CIDR; vrf = scope VRF; is_pool = false; description = Allocated from IPAM Pool <pool_id>; ResourceType=<type>, ResourceId=<id>, carrying the pool's name and description when set
IPAM resource CIDR, non-host (get_ipam_resource_cidrs)Prefixprefix = the resource CIDR; vrf = VPC VRF when the row has a VpcId, otherwise scope VRF; status = container for a vpc row, otherwise the NetBox default; description as described in Prefix and IP address descriptions
IPAM resource CIDR, single host (/32 IPv4 or /128 IPv6)IPAddressaddress = the host CIDR; vrf = VPC VRF when the row has a VpcId, otherwise scope VRF; description as described in Prefix and IP address descriptions

VRF name enrichment

The scope VRF name is derived from the IPAM scope's tags. If the scope has a Name tag with a non-empty value, that value is used as the VRF name after trimming surrounding whitespace. If the Name tag is unset, empty, or whitespace-only, the VRF name falls back to the scope ID (for example ipam-scope-08c06b7b3f4853315).

NetBox limits VRF.name to 100 characters. A Name tag longer than 100 characters is truncated to fit, and a warning is logged.

VPC VRFs are always named after the VpcId, not an AWS Name tag, because two VPCs can share a Name while the VpcId is globally unique.

VRF assignment and overlapping CIDRs

  • Scope VRFs hold pool inventory (provisioned CIDRs and allocations) and any resource CIDRs that do not carry a VpcId (for example unattached Elastic IPs).
  • VPC VRFs are created for resource CIDRs that carry a VpcId, keyed on the VpcId. This gives each VPC its own routing-isolation boundary in NetBox so that overlapping CIDRs across VPCs (for example dev, staging, and prod all on 10.0.0.0/16) coexist without colliding on the NetBox (prefix, vrf) uniqueness constraint.
  • A VPC and a subnet with the same CIDR would map to the same NetBox prefix in the VPC VRF. The integration sends one prefix for them, and the VPC row wins: the prefix gets the container status and the VPC's description.

Route distinguisher (RD) scheme

Both VRF kinds set an RD to guarantee uniqueness and traceability while staying within the NetBox 21-character RD limit:

  • Scope VRF: ScopeID: + the last 13 hexadecimal characters of the scope ID (for example ScopeID:6b7b3f4853315).
  • VPC VRF: VPC: + the last 13 hexadecimal characters of the VPC ID (for example VPC:b19444de235e8).

Host address handling

Resource CIDRs with a /32 (IPv4) or /128 (IPv6) mask are modeled as NetBox IPAddress objects rather than prefixes. AWS IPAM represents single-host Elastic IPs this way. All other resource CIDRs become prefixes.

Prefix status

A prefix built from a resource CIDR whose ResourceType is vpc is set to NetBox's built-in container status. A VPC CIDR is the aggregate that holds its subnets, which is what the container status models, and it makes the standard "show me the aggregates" status filter work without extra setup.

Every other resource type keeps NetBox's default prefix status.

The integration does not create or assign a NetBox Role on any object. It uses the native status field only, so it cannot collide with a prefix role you curate yourself. It creates no Tenant objects either, for the same reason.

Prefix and IP address descriptions

Descriptions are generated from the AWS data and clamped to NetBox's 200-character description limit.

Pool prefixes lead with the machine-readable origin, then carry the pool's identity when the AWS pool has a Name tag, a description, or both:

Provisioned from IPAM Pool ipam-pool-0a1b2c3d4e5f (NetBox-Test-Pool: Private IPAM pool for the NetBox integration)

Resource CIDRs use one of two forms. A vpc or subnet row whose AWS name resolves - from ResourceName, or from a Name tag in ResourceTags - leads with that name:

VPC: terraform-vpc (vpc-0784ae5cc3099b2a0) | Compliance=unmanaged

Every other resource type, and any vpc or subnet row with no name, uses the raw form:

ResourceType=eni, ResourceId=eni-0a1b2c3d4e5f, Compliance=compliant

Compliance comes straight from AWS and is included only when AWS reports a compliance status. Subnet rows never carry one, so a named subnet reads, for example, Subnet: az1 (subnet-02c7b76d0fa571ffb). IPAM's utilization figure is not included, because AWS recalculates it continuously and it would change the description on every sync.

Configuration keys

All keys are read from the policy config block.

KeyRequiredDefaultDescription
AWS_VPC_IPAM_REGIONYesnoneHome region of each IPAM to sync, not the regions it operates in. An IPAM's resources from all of its operating regions are read through its home region. See Home region and operating regions. Accepts a single region string (us-east-1), a comma-separated string (us-east-1,eu-west-1), or a YAML list. Region codes are lowercased and de-duplicated. The run fails if no valid region is parsed.
AWS_ACCESS_KEY_IDNounset (default credential chain)Access key ID of the identity that reads IPAM. Must be set together with AWS_SECRET_ACCESS_KEY; omit both to fall back to the default credential chain.
AWS_SECRET_ACCESS_KEYNounset (default credential chain)Secret access key paired with AWS_ACCESS_KEY_ID. Supply it through ${...} substitution rather than in plain text.
AWS_SESSION_TOKENNounsetSession token for temporary credentials. Only valid alongside AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Temporary credentials expire, so use it for ad hoc testing, not for a scheduled sync.
AWS_VPC_IPAM_SCOPE_TYPENoprivateFilters IPAM scopes by type. One of private, public, or all. An invalid value fails the run.
AWS_VPC_IPAM_SCOPE_IDSNounset (all scopes)Comma-separated string or YAML list of IPAM scope IDs to ingest. Applied on top of AWS_VPC_IPAM_SCOPE_TYPE, so a public scope ID listed here is not ingested while the scope type is private, and no warning is logged for it. Case-sensitive.
AWS_VPC_IPAM_RESOURCE_TYPESNounset (all types)Comma-separated string or YAML list of resource-CIDR types to ingest. Matched case-insensitively against ResourceType. Applies to resource CIDRs only, not to pool allocations. A value that matches no resource type is not reported.
AWS_ROLE_ARNNounsetIAM role ARN to assume via sts:AssumeRole before building the EC2 client, enabling cross-account ingestion.
AWS_ROLE_SESSION_NAMENonetbox-orb-agent-aws-vpc-ipamSession name for the assumed role. Only used when AWS_ROLE_ARN is set. Surfaces in the target account's CloudTrail.

Do not write secrets into the policy file in plain text. When the policy loads, a config value that is exactly a ${...} reference is replaced with the matching environment variable from the agent process. Orb Agent can additionally resolve secrets from an external store such as HashiCorp Vault, configured separately under orb.secrets_manager and referenced with its own ${vault://...} form.

There is no BOOTSTRAP key for this integration. It creates no custom fields or other static content, so no bootstrap run is required.

Authentication

You run the agent and you hold the credentials. The integration builds a boto3 EC2 client per region from a base identity, resolved in this order:

  1. Credentials from the policy config - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, plus AWS_SESSION_TOKEN for temporary credentials. These take precedence over everything else.
  2. The default boto3 credential chain - used only when neither config key is set. No credentials are passed to boto3, so its standard chain applies: an attached instance or task role when the agent runs inside AWS, otherwise whatever that chain resolves from the agent's own environment or AWS config files.

If AWS_ROLE_ARN is set, the base identity from step 1 or 2 calls sts:AssumeRole against that role, and the returned short-lived credentials build the EC2 client. The role is assumed once per region, so credentials stay fresh on long multi-region runs.

AWS_ROLE_ARN is for assuming a role you own, in another AWS account you own. The role is assumed by the agent you run, with your own base identity, and no External ID is sent.

A credential key that is present but empty fails the run rather than falling back to another identity, so it cannot silently read IPAM under an unintended one. An unset environment variable behind a ${...} reference is a different case: the reference is left in place as literal text and passed to AWS, which rejects it and aborts the run.

Least-privilege IAM policy

The integration only reads. The six actions below are the complete set it calls, so it needs no write, modify, or delete permission anywhere in your account:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeIpams",
        "ec2:DescribeIpamScopes",
        "ec2:DescribeIpamPools",
        "ec2:GetIpamPoolCidrs",
        "ec2:GetIpamPoolAllocations",
        "ec2:GetIpamResourceCidrs"
      ],
      "Resource": "*"
    }
  ]
}

For cross-account access, the source identity additionally needs sts:AssumeRole on the target role ARN, and the target role's trust policy must allow the source identity to assume it. The target role carries the IPAM read actions above. sts:AssumeRole is only ever used to reach your own accounts.

AWS APIs used

  • describe_ipams - IPAM instances in the region
  • describe_ipam_scopes (filtered by ipam-id) - scopes per IPAM
  • describe_ipam_pools (filtered by ipam-scope-id) - pools per scope
  • get_ipam_pool_cidrs - provisioned CIDRs per pool (paginated, 100 per page)
  • get_ipam_pool_allocations - allocations per pool (paginated, 1000 per page)
  • get_ipam_resource_cidrs (filtered by ipam-scope-id) - resource CIDRs per scope (paginated, 1000 per page)
  • sts:AssumeRole - only when AWS_ROLE_ARN is set

Tags and metadata

Every object created by the integration is tagged with:

  • aws-vpc-ipam - the integration identity tag applied to all objects
  • aws:<region> - a per-region tag (for example aws:us-east-1) that conveys region grouping. The region is the one in AWS_VPC_IPAM_REGION that the object was read through, which is the IPAM's home region. A subnet in an operating region, such as eu-west-1, of an IPAM homed in us-east-1 is tagged aws:us-east-1.

Region grouping is expressed only through the aws:<region> tag. No Tenant is created or assigned, so customers can filter and group by region without the integration imposing a tenant structure on their NetBox data.

Multi-region behavior

Home region and operating regions

An AWS VPC IPAM is created in one region, its home region, and can operate in other regions. The integration reads each IPAM through its home region, and that returns the scopes, pools, and resource CIDRs of every operating region. List only home regions in AWS_VPC_IPAM_REGION:

  • One IPAM homed in us-east-1 that operates in us-east-1 and eu-west-1: set AWS_VPC_IPAM_REGION: us-east-1. VPCs and subnets from both regions are synced.
  • Two IPAMs, one homed in us-east-1 and one in ap-south-1: set both regions.

A listed region that is not the home region of any IPAM logs the warning No IPAMs found in region <region> and contributes nothing. This is harmless, and the other regions are still synced. To find an IPAM's home region, open the IPAM in the AWS console, or run aws ec2 describe-ipams and check IpamRegion.

Per-region processing

Each region in AWS_VPC_IPAM_REGION is processed independently. An AWS-side failure on one region (throttling, IAM denial, or IPAM not enabled) is logged as Error processing region <region>: <error> and skipped, and the run continues with the remaining regions. Missing or incomplete AWS credentials, or a failure to assume the cross-account role, abort the entire run because those errors are global rather than per-region.

When you supply credentials in the policy config, AWS rejecting them - an invalid, inactive, or expired key - also aborts the whole run. That failure would repeat identically in every region, so the run stops with one clear error instead of logging the same rejection per region and reporting an empty success. With credentials from the default boto3 chain, such as an instance role, a rejection is logged per region instead, and a run in which every region fails ends with the warning No entities built from AWS VPC IPAM.

If AWS_VPC_IPAM_SCOPE_IDS lists a scope ID that is not found in any processed region, a warning is logged so you can check for typos or a scope that belongs to a region not in AWS_VPC_IPAM_REGION.

Known limitations

  • The integration never deletes. Applying its deviations creates and updates objects; one that no longer exists in AWS is left untouched rather than removed, so there is no stale-object detection.
  • Data flows one way only. The integration does not push scopes or pools from NetBox back to AWS VPC IPAM.
  • The integration only reads from AWS VPC IPAM. It does not discover IP information through other AWS endpoints.

On this page