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.

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 | Usage=0.0234

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

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

Compliance and Usage come straight from AWS, and Usage is a utilisation figure that AWS recomputes as address consumption changes. Treat this description format as provisional: it is under review, because a value that moves on its own reads as operational drift on every sync. Do not build automation that parses it.

Configuration keys

All keys are read from the policy config block.

KeyRequiredDefaultDescription
AWS_VPC_IPAM_REGIONYesnoneAWS region to sync. 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. 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.
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. NetBox Labs never assumes a role in your AWS account, so no External ID is involved.

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

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

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 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.

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. Object lifecycle management, including deletes, is coming soon.
  • After a run that predates per-VPC VRFs, resource-CIDR prefixes created under scope VRFs by earlier runs are not migrated to VPC VRFs.
  • 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