DEV Community

My notes on AWS IPAM

AWS IPAM helps you avoid IP address conflicts by providing a single source of truth for CIDR allocation. It also offers features such as monitoring usage and compliance across accounts and regions—but those are out of scope here.

In this post, I focus on a very basic (and very common) use case: using AWS IPAM to allocate a non‑overlapping CIDR for a newly created VPC. How hard can that be? As it turns out, not very—but there are some practical gotchas worth knowing about. This post is a collection of those lessons learned.


What works well

Seamless VPC integration

Once AWS IPAM is configured, CIDR allocation for VPCs is refreshingly simple. To appreciate this, consider some non‑seamless alternatives:

  • A CloudFormation custom resource that triggers on VPC creation and pulls the next free CIDR from an on‑prem IPAM
  • A mix of bash scripting in CI/CD pipelines and IaC templates
  • Manual Excel bookkeeping combined with click‑ops (😱)

With AWS IPAM, none of that is needed. VPC creation can look as simple as this:

resource "aws_vpc" "test" {
  ipv4_ipam_pool_id   = "my-ipam-pool-id"
  ipv4_netmask_length = 21
}
Enter fullscreen mode Exit fullscreen mode

AWS IPAM automatically picks the next available /21 from the pool. When the VPC is deleted, the CIDR is returned to the pool (typically within ~10 minutes) and becomes available for reuse. If the account holding the VPC is deleted, VPC allocation stays in the pool until 90-days post-closure period has passed.


IP pools

IP pools are a core IPAM concept and work largely as expected. You can:

  • Build a hierarchical structure (e.g. company → department → region → environment)
  • Use a flat structure(e.g. all-eu-west-1-cidrs)
  • Combine both approaches.

Each pool contains one or more provisioned CIDR blocks. When a pool runs out of free address space, you can add additional CIDRs, and AWS IPAM will automatically start using them for future allocations.


Sharing pools across accounts

IPAM pools can be shared with other AWS accounts using AWS RAM. If your AWS Organization is structured with OUs (as it should be), this works nicely:

  • Share production pools with production OUs
  • Share non‑prod pools with non‑prod OUs

Note: Accounts that receive a shared pool can see all allocations within that pool, including VPC ID, CIDR, and Account ID.


Importing existing VPC CIDRs

If you already have VPCs with manually assigned CIDRs—or CIDRs allocated via other automation—AWS IPAM can import those existing VPCs into pools.

Think of this as syncing your current state into AWS IPAM. From that point on, you can confidently allocate CIDRs for new VPCs, knowing that overlaps are prevented.


What doesn’t work so well

Pricing

AWS IPAM pricing is based on managed IP addresses per hour. When integrated with AWS Organizations, you are billed for every IP address in use.

You can mark CIDR blocks in IPAM as ignored, in which case AWS skips managing those ranges—but any IP addresses actively in use are still billed.


Missing features

The core functionality works well, but several advanced (yet very reasonable) features are missing:

  • Configurable de‑allocation grace periods:
    When a VPC is deleted, its CIDR is released back to the pool after ~10 minutes. In some environments, you might want:

    • A multi‑day grace period (e.g. 10 days)
    • Manual approval before reuse
  • More useful pool‑level metrics:

    Pool utilization is reported only as a percentage. Metrics such as "IP addresses remaining" would make it much easier to build meaningful alarms across pools of different sizes.

  • Events for allocations and de‑allocations:

    VPC CIDR allocation and release events would be extremely useful for automation and auditing purposes. Those would make it easier also to implement custom workarounds for missing features like grace period. Now only way is to periodically poll IPAM pools for changes. Polling will be discussed further on the next section.

  • Weighted CIDR blocks at pool level:

    In most cases, you are having multiple CIDRs on the pool. It would be beneficial to have control which one is used first for VPC allocations. This would enable more efficient CIDR usage.


Things to be aware of

Regions and locale

AWS IPAM itself is created in a single region, but it can manage pools across multiple regions.

For example:

  • IPAM is created in eu-west-1 home region.
  • Pools exist in eu-west-1 and eu-north-1

In IPAM terminology, each pool has a locale (its region).

UI vs API behavior

  • AWS Console:
    All pools and allocations are visible in the region where IPAM is created, regardless of pool locale. Same behaviour continues on share recipient accounts. All pool shares are visible on RAM in the home region but the pool can be used only on the region specified by pool locale.

  • AWS CLI / SDK:
    This is where things get tricky. You must query pool allocations from the same region as the pool’s locale. Pool CIDRs then again must be queried from the same region where AWS IPAM is deployed. The result is sligthly awkward control flow. You end up juggling multiple boto3 clients, each valid only for a specific subset of API calls.

Example using boto3:

ec2 = boto3.client("ec2", region_name="eu-west-1")

# Works. Pool is on the same region as AWS IPAM
ec2.get_ipam_pool_cidrs(IpamPoolId="EU-WEST-1-ID")
ec2.get_ipam_pool_allocations(IpamPoolId="EU-WEST-1-ID")

# Does NOT work. 
ec2.get_ipam_pool_allocations(IpamPoolId="EU-NORTH-1-ID")

# Correct approach. Get boto3 client on the same region as pool locale.
ec2_eun1 = boto3.client("ec2", region_name="eu-north-1")
ec2_eun1.get_ipam_pool_allocations(IpamPoolId="EU-NORTH-1-ID")
Enter fullscreen mode Exit fullscreen mode

Resource discovery quirks

AWS IPAM Resource Discovery keeps an inventory of IP address usage across accounts, but its behavior is not always consistent.
Overall there is a strict separation of duties between IPAM Pools and IPAM Resource Discovery. For example, you can't use Resource Discovery to query the IPAM pool from which a VPC was allocated. Conversely, if you need to access VPC tags, those are exposed only via Resource Discovery and are not available at the IPAM pool level.

Because of these inconsistencies and syncing issues, getting VPC configuration which contains pool level data requires active polling from both IPAM pool and Resource Discovery.

For common VPC operations IPAM behaves as follows:

  • When a VPC is created using an IPAM pool, the CIDR allocation is immediately visible in the pool, but it may take several minutes before the corresponding VPC shows up in Resource Discovery.

  • When an AWS account is closed:

    • VPCs disappear from Resource Discovery almost immediately
    • CIDR allocations remain associated with the pool
    • After the ~90 days post-closure period after the account is permanently deleted, the CIDRs are released back to the pool

Conclusion

AWS IPAM solves the core problem it’s meant to solve: allocating non-overlapping CIDRs for VPCs without custom automation or human bookkeeping. However, there is still a somewhat unfinished feel, with missing events for automation and region/locale quirks that are easy to trip over. This pushes you to build workarounds for missing or incomplete features—something that ideally shouldn’t be necessary for a managed AWS service.

Pricing can also become noticeable in large environments. Billing is based on managed IP addresses per hour, so organizations with many accounts and large CIDR ranges should do the math upfront.

And hey, since it’s almost Christmas, here’s my wish: ditch AWS IPAM Resource Discovery altogether. Keep monitoring at the VPC / subnet level, no need to track ENI-level details. Attach VPC metadata (like tags) directly to pool allocations. And emit pool lifecycle and allocation events to Eventbridge. Keep it simple. And please, make it free — or at least charge per VPC.

Top comments (0)