Documentation Index
Fetch the complete documentation index at: https://mintlify.com/OpsMill/infrahub/llms.txt
Use this file to discover all available pages before exploring further.
Infrahub provides a full-featured IPAM system for managing IP addresses, prefixes, and namespaces with automatic hierarchy reconciliation.
IPAM Hierarchy
Infrahub IPAM uses a parent-child hierarchy:
Namespace: default
├── 10.0.0.0/8 (parent)
│ ├── 10.0.0.0/16 (child)
│ │ ├── 10.0.1.0/24 (child)
│ │ │ ├── 10.0.1.1/32 (IP address)
│ │ │ ├── 10.0.1.2/32 (IP address)
│ │ │ └── 10.0.1.3/32 (IP address)
│ │ └── 10.0.2.0/24 (child)
│ └── 10.1.0.0/16 (child)
The IPAM reconciler automatically maintains this hierarchy when you create, update, or delete prefixes.
IP Namespaces
Namespaces provide isolation for overlapping IP space (e.g., multi-tenant, VRFs, environments).
Creating a Namespace
- Navigate to IPAM → Namespaces
- Click Add Namespace
- Set Name and Description
- Click Save
mutation {
IpamNamespaceCreate(
data: {
name: { value: "production" }
description: { value: "Production network namespace" }
}
) {
ok
object {
id
display_label
}
}
}
from infrahub_sdk import InfrahubClient
client = InfrahubClient()
namespace = await client.create(
kind="IpamNamespace",
name="production",
description="Production network namespace"
)
await namespace.save()
The default namespace is created automatically during Infrahub initialization.
IP Prefixes
Prefixes represent network subnets (e.g., 10.0.1.0/24, 2001:db8::/32).
Creating a Prefix
- Navigate to IPAM → Prefixes
- Click Add Prefix
- Set:
- Prefix: CIDR notation (e.g.,
10.0.1.0/24)
- IP Namespace: Select namespace
- Status: Active, reserved, deprecated, etc.
- Member Type: Prefix or pool
- Description: Purpose of the prefix
- Click Save
The IPAM reconciler automatically sets the parent-child relationships.mutation {
IpamIPPrefixCreate(
data: {
prefix: { value: "10.0.1.0/24" }
ip_namespace: { hfid: ["default"] }
status: { value: "active" }
member_type: { value: "prefix" }
description: { value: "Atlanta site network" }
}
) {
ok
object {
id
prefix { value }
parent { id } # Automatically set
is_top_level { value } # Auto-calculated
}
}
}
from infrahub_sdk import InfrahubClient
client = InfrahubClient()
# Get the namespace
namespace = await client.get(
kind="IpamNamespace",
name__value="default"
)
# Create prefix
prefix = await client.create(
kind="IpamIPPrefix",
prefix="10.0.1.0/24",
ip_namespace=namespace.id,
status="active",
member_type="prefix",
description="Atlanta site network"
)
await prefix.save()
# Reconcile the IPAM hierarchy
from infrahub.core.ipam.reconciler import IpamReconciler
import ipaddress
reconciler = IpamReconciler(db=db, branch=branch)
await reconciler.reconcile(
ip_value=ipaddress.ip_network("10.0.1.0/24"),
namespace=namespace.id,
node_uuid=prefix.id
)
IPAM Reconciliation
The IpamReconciler automatically maintains the parent-child hierarchy:
from infrahub.core.ipam.reconciler import IpamReconciler
import ipaddress
reconciler = IpamReconciler(db=db, branch=branch)
# Reconcile after creating/updating a prefix
await reconciler.reconcile(
ip_value=ipaddress.ip_network("10.0.1.0/24"),
namespace=namespace_id,
node_uuid=prefix_id
)
Reconciliation:
- Finds the closest parent prefix (longest prefix match)
- Sets the
parent relationship
- Updates
is_top_level flag
- Moves orphaned children to the new parent
- Updates
children and ip_addresses relationships
Prefix Queries
Find prefixes by various criteria:
query {
IpamIPPrefix(
prefix__value: "10.0.1.0/24"
ip_namespace: { name: { value: "default" } }
) {
edges {
node {
id
prefix { value }
parent {
id
prefix { value }
}
children {
edges {
node {
prefix { value }
}
}
}
ip_addresses {
edges {
node {
address { value }
}
}
}
}
}
}
}
IP Addresses
IP addresses are specific IPs within prefixes (e.g., 10.0.1.5/32).
Creating an IP Address
- Navigate to IPAM → IP Addresses
- Click Add IP Address
- Set:
- Address: IP with prefix length (e.g.,
10.0.1.5/32)
- IP Namespace: Select namespace
- Status: Active, reserved, etc.
- Description: What uses this IP
- Click Save
The IPAM reconciler automatically links the IP to its parent prefix.mutation {
IpamIPAddressCreate(
data: {
address: { value: "10.0.1.5/32" }
ip_namespace: { hfid: ["default"] }
status: { value: "active" }
description: { value: "Web server" }
}
) {
ok
object {
id
address { value }
ip_prefix { id } # Automatically set by reconciler
}
}
}
from infrahub_sdk import InfrahubClient
client = InfrahubClient()
namespace = await client.get(
kind="IpamNamespace",
name__value="default"
)
ip_address = await client.create(
kind="IpamIPAddress",
address="10.0.1.5/32",
ip_namespace=namespace.id,
status="active",
description="Web server"
)
await ip_address.save()
Assigning IPs to Interfaces
Link IP addresses to device interfaces:
mutation {
IpamIPAddressUpdate(
data: {
id: "<ip-address-uuid>"
interface: { id: "<interface-uuid>" }
}
) {
ok
}
}
Or create the IP with the interface:
mutation {
IpamIPAddressCreate(
data: {
address: { value: "10.0.1.5/32" }
ip_namespace: { hfid: ["default"] }
interface: { id: "<interface-uuid>" }
}
) {
ok
object {
id
}
}
}
Resource Allocator
The IPAMResourceAllocator finds the next available prefix or IP address.
Allocating Prefixes
from infrahub.core.ipam.resource_allocator import IPAMResourceAllocator
import ipaddress
allocator = IPAMResourceAllocator(
db=db,
namespace=namespace,
branch=branch,
branch_agnostic=True # Search across all branches
)
# Get next available /24 from 10.0.0.0/16
parent_prefix = ipaddress.ip_network("10.0.0.0/16")
next_prefix = await allocator.get_next_prefix(
ip_prefix=parent_prefix,
target_prefix_length=24
)
print(f"Next available /24: {next_prefix}")
# Output: 10.0.1.0/24 (if 10.0.0.0/24 is already used)
The allocator:
- Queries all child prefixes using
IPPrefixSubnetFetchFree
- Calculates gaps in the address space
- Returns the first available prefix of the requested length
Allocating IP Addresses
from infrahub.core.ipam.resource_allocator import IPAMResourceAllocator
import ipaddress
allocator = IPAMResourceAllocator(db=db, namespace=namespace, branch=branch)
# Get next available IP from 10.0.1.0/24
prefix = ipaddress.ip_network("10.0.1.0/24")
next_ip = await allocator.get_next_address(ip_prefix=prefix)
print(f"Next available IP: {next_ip}")
# Output: 10.0.1.1 (skips network address 10.0.1.0)
By default, the allocator skips:
- Network address (first IP)
- Broadcast address (last IP)
For pools where these are usable:
next_ip = await allocator.get_next_address(
ip_prefix=prefix,
is_pool=True # Allow network and broadcast
)
IPv6 Support
The allocator handles IPv6’s 128-bit address space using binary string operations:
import ipaddress
# Allocate IPv6 prefix
parent = ipaddress.ip_network("2001:db8::/32")
next_prefix = await allocator.get_next_prefix(
ip_prefix=parent,
target_prefix_length=48
)
# Allocate IPv6 address
prefix = ipaddress.ip_network("2001:db8:1::/64")
next_ip = await allocator.get_next_address(ip_prefix=prefix)
Prefix Utilization
Query prefix utilization to monitor capacity:
query {
IpamIPPrefix(prefix__value: "10.0.0.0/16") {
edges {
node {
prefix { value }
utilization
children {
count
}
ip_addresses {
count
}
}
}
}
}
Or use the utilization API:
from infrahub.core.ipam.utilization import get_prefix_utilization
util = await get_prefix_utilization(
db=db,
prefix_id=prefix_id,
branch=branch
)
print(f"Utilization: {util.percentage:.1f}%")
print(f"Used: {util.used} / {util.total}")
IPAM with Resource Manager
Combine IPAM with Resource Manager for automatic allocation (see Resource Manager guide):
# Create IP Prefix Pool
pool = await client.create(
kind="CoreIPPrefixPool",
name="Site Subnets",
ip_namespace=namespace.id,
default_prefix_length=24,
resources=[parent_prefix.id]
)
await pool.save()
# Allocate from pool
prefix = await pool.get_resource(
db=db,
branch=branch,
identifier="site-atl1",
prefixlen=24
)
This creates the prefix and reconciles the IPAM hierarchy automatically.
Best Practices
- Use namespaces: Isolate IP space by tenant, environment, or VRF
- Let reconciliation work: Don’t manually set
parent relationships
- Allocate top-down: Create large prefixes first, then subdivide
- Track assignments: Link IPs to interfaces for visibility
- Monitor utilization: Set alerts at 80% capacity
- Use pools: Automate allocation with Resource Manager pools
- Reserve network IPs: Mark .0 and .255 as reserved
- Document prefixes: Use
description to explain purpose
Common Patterns
Hierarchical Allocation
# 1. Create regional prefix
regional = await client.create(
kind="IpamIPPrefix",
prefix="10.0.0.0/16",
description="US East region"
)
# 2. Create site prefixes
site1 = await client.create(
kind="IpamIPPrefix",
prefix="10.0.1.0/24",
description="Atlanta site"
)
# 3. Allocate IPs for devices
ip1 = await client.create(
kind="IpamIPAddress",
address="10.0.1.1/32",
description="Gateway"
)
The reconciler automatically links: regional → site1 → ip1
Multi-Tenant IPAM
# Create namespace per tenant
for tenant in ["acme", "globex", "initech"]:
ns = await client.create(
kind="IpamNamespace",
name=tenant
)
await ns.save()
# Each tenant can use the same IP space
prefix = await client.create(
kind="IpamIPPrefix",
prefix="10.0.0.0/16",
ip_namespace=ns.id
)
await prefix.save()
Next Steps